Kmart Lied to Me, So I Hacked Their Lamp

The Problem

Have you ever bought something that seemed perfect—only to find one or two features that completely ruin it for you? That’s exactly what happened to me with a $17 mushroom lamp from Kmart. And yes, Kmart straight-up lied to me.

The Kmart Inaya Lamp

On paper, these lamps are fantastic. USB-C rechargeable, solid construction, beautiful diffused light—perfect for a bedside table. But there’s one fatal flaw: the USB-C port doesn’t work.

I tried charging the lamp with the same cable I use for my phone. Nothing. Dead. Then I noticed a tiny tag on the included USB-C cable. Plugged that in, and—voila! It charged.

But here’s the kicker: this cable isn’t really USB-C. It uses the connector, but it doesn’t follow the USB-C standard. As a result, modern chargers don’t recognize it, and the lamp won’t charge.

This means if you lose the cable, your lamp becomes e-waste. It’s a decision that likely saved Kmart a few cents per unit—but makes the user experience way worse. Even worse, that dodgy cable could potentially fry your other devices.

For most people, this might be a minor inconvenience. But for me? Unacceptable. USB-C was supposed to be the one connector to rule them all. I’m not keeping a special cable around just for a $17 lamp.

Making a Plan

So, I picked up another lamp, purely to dissect it and figure out a fix. Inside, it’s a zip-tied, hot-glued hodgepodge of wires, modules, and a tiny battery. Here’s the breakdown:

  • A single PCB controls everything: touch sensor, battery, LED, and USB port.

  • Brightness is adjusted via PWM (pulse width modulation), which flashes the LED at high speed to create different light levels.

  • The included charging circuit is basic, relying on the janky USB cable to deliver 4.2V to a lithium-ion battery zip-tied inside.

Instead of just fixing the USB-C port, I decided to replace the entire PCB with an ESP32 board running ESPHome. Here’s why:

  • The ESP32 has its own charging circuit.

  • It supports touch input—so we can reuse the original button.

  • It gives us full control via Home Assistant.

To safely power the LEDs, I used a MOSFET—essentially an electronic switch that lets us control higher currents with a low-power signal.

Making the Modifications

  1. Drill out the USB port hole to fit a proper USB-C extension cable.

  2. 3D print custom washers to hold it in place.

  3. Wire up a MOSFET on stripboard and connect it to the ESP32.

  4. Fix the battery connector polarity to match the ESP32’s requirements.

  5. Reassemble everything—insulating the components with heat shrink and tape.

ESP Home YAML

esphome:
  name: Bedside Lamp
  friendly_name: Bedside Lamp
  min_version: 2024.11.0
  name_add_mac_suffix: false

esp32:
  board: esp32dev
  framework:
    type: esp-idf

logger:
  level: NONE

api:

ota:
  - platform: esphome

wifi:
  ssid: "YOUR_SSID"
  password: "YOUR_PW"
  power_save_mode: LIGHT

captive_portal:

esp32_touch:

output:
  - platform: ledc
    pin: GPIO12
    id: pwm_led
    frequency: 1000 Hz

light:
  - platform: monochromatic
    output: pwm_led
    id: touch_led
    name: "Touch LED"
    restore_mode: RESTORE_DEFAULT_OFF

globals:
  - id: single_tap_flag
    type: bool
    restore_value: no
    initial_value: 'false'

  - id: double_tap_flag
    type: bool
    restore_value: no
    initial_value: 'false'

  - id: long_press_flag
    type: bool
    restore_value: no
    initial_value: 'false'

binary_sensor:
  - platform: esp32_touch
    pin: GPIO32
    threshold: 800
    id: touch_button
    internal: true

    on_multi_click:
      - timing:
          - ON for 30ms to 600ms
        then:
          - script.execute: handle_single_tap

      - timing:
          - ON for 30ms to 600ms
          - OFF for 30ms to 600ms
          - ON for 30ms to 600ms
        then:
          - script.stop: handle_single_tap
          - globals.set:
              id: double_tap_flag
              value: 'true'
          - delay: 300ms
          - globals.set:
              id: double_tap_flag
              value: 'false'

      - timing:
          - ON for at least 800ms
        then:
          - script.stop: handle_single_tap
          - globals.set:
              id: long_press_flag
              value: 'true'
          - delay: 300ms
          - globals.set:
              id: long_press_flag
              value: 'false'


  - platform: template
    name: "Single Tap"
    lambda: |-
      return id(single_tap_flag);
    internal: false

  - platform: template
    name: "Double Tap"
    lambda: |-
      return id(double_tap_flag);
    internal: false

  - platform: template
    name: "Long Press"
    lambda: |-
      return id(long_press_flag);
    internal: false

sensor:
  - platform: adc
    pin: GPIO35
    id: battery_voltage
    internal: true
    update_interval: 120s
    attenuation: 11db
    filters:
      - multiply: 24.7

  - platform: template
    name: "Battery Level"
    unit_of_measurement: "%"
    icon: "mdi:battery"
    update_interval: 120s
    lambda: |-
      if (id(battery_voltage).state >= 4.2) {
        return 100;
      } else if (id(battery_voltage).state <= 3.2) {
        return 0;
      } else {
        return (id(battery_voltage).state - 3.2) * 100.0 / (4.2 - 3.2);
      }

script:
  - id: handle_touch_press
    mode: restart
    then:
      - if:
          condition:
            light.is_off: touch_led
          then:
            - light.turn_on: touch_led
          else:
            - light.turn_off: touch_led

  - id: handle_single_tap
    mode: restart
    then:
      - delay: 400ms
      - globals.set:
          id: single_tap_flag
          value: 'true'
      - script.execute: handle_touch_press
      - delay: 200ms
      - globals.set:
          id: single_tap_flag
          value: 'false'

interval:
  - interval: 60s
    then:
      - lambda: |-
          ESP_LOGI("battery", "Battery voltage: %.2f V", id(battery_voltage).state);

Automations

With everything wired up, it was time to write a few lines of YAML in ESPHome. Simple automations like:

  • Tap = toggle light

  • Double tap = control both bedside lamps

  • Hold = turn off lights, lock front door, and shut down the rest of the house

These automations turned our little lamps from occasional-use gimmicks into core parts of our nighttime routine. Now they light up when the TV turns off, when we enter the room at night, or when the alarm goes off in the morning.

Parts List / Wiring Diagram

Here are the parts I used in this project:

  • ESP32 Development BoardLonely Binary | Aliexpress Clone

  • USB-C Extension Cable Ebay (Can’t find the ones I bought anymore, but these look the same, but way more expensive)

  • N-Channel MOSFETsAmazon

  • Kmart Inaya Mushroom LampKmart

Conclusion

I can’t take credit for the design of the lamp, but I can take credit for making it massively more functional.

Each upgraded lamp cost about $7 in parts and one afternoon of work, bringing the total to under $25. And now? They charge with any USB-C cable, integrate with Home Assistant, and actually serve a useful role in our day-to-day life.

If you're like me—tired of cheap products cutting corners—this project might be worth replicating.


And Kmart? Do better.


Thanks for reading! Catch you next time.

Previous
Previous

My TV Remote Stopped Working… So I Made My Own.

Next
Next

I'm building a smart home that doesn't suck