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.

  • esphome:

      name: esphome-web-7a1154

      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:

          # Single Tap

          - timing:

              - ON for 30ms to 600ms

            then:

              - script.execute: handle_single_tap


          # Double 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'


          # Long Press

          - 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'es here

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.

Next
Next

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