SmartKnight ML Accessories Ltd - Smart Plug

@karldonteljames I don’t suppose you’d be willing to sell and exchange? I just don’t have the knowledge to be able to do this, but would really like to do it.

Just flashed two of them successfully! Many, many thanks @maxwroc !

I’m struggling to get the earth plate back into the rivet. How did everyone go about it?

1 Like

I’m having a similar issue to @Vas with getting the rivets back in place, anyone got any good tips for this?

I ended up just tightening brass bolts in their place. I’ve had them installed for 2 months now.

Hey, I just submitted a PR to your config Add HA calibration service by vasileio · Pull Request #2 · DJBenson/ha-stuff · GitHub

I had Tasmota running on 2 of these for more than half a year, totally happy with it, but I thought I would bring everything to ESPHome. I copied another project’s config: GitHub - JamesSwift/localbytes-plug-pm: An ESPHome firmware for the Localbytes smart plug that uses the HA calibration feature which makes it a breeze, so I get very accurate readings after this.

To go from Tasmota to ESPHome without serial flashing, I had to upload a super minimal ESPHome configuration which was basically just an OTA app:

esphome:
  name: garden-sockets

esp8266:
  board: esp01_1m

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

ota:
  platform: esphome

After that I could flash the configuration I submitted through a PR to your repo, for easier reference of future readers:

substitutions:
  # Short placeholders for reuse in the config
  name: knightsbridge-cu9kw             # Used as the device hostname/mDNS name
  friendly_name: Knightsbridge-CU9KW    # Human-readable label for UIs

esphome:
  name: $name
  on_boot:
    priority: 300
    then:
      # Initialise multipliers if they haven't been set yet
      - lambda: |-
          if (id(voltage_multiply) <= 0) id(voltage_multiply) = 0.3;
          if (id(power_multiply)   <= 0) id(power_multiply)   = 0.133;
          if (id(current_multiply) <= 0) id(current_multiply) = 0.805;
      - globals.set:
          id: setupComplete
          value: "true"               # Flag indicating calibration values are initialised

esp8266:
  board: esp01_1m

# Enable logging
logger:

# Enable Home Assistant API and calibration services
api:
  encryption:
    key: !secret api_key
  services:
    - service: calibrate_voltage
      variables:
        actual_value: float
      then:
        - lambda: |-
            id(voltage_multiply) = actual_value / id(voltage).raw_state;
        - number.set:
            id: voltage_factor
            value: !lambda "return id(voltage_multiply);"
    - service: calibrate_power
      variables:
        actual_value: float
      then:
        - lambda: |-
            id(power_multiply) = actual_value / id(power).raw_state;
        - number.set:
            id: power_factor
            value: !lambda "return id(power_multiply);"
    - service: calibrate_current
      variables:
        actual_value: float
      then:
        - lambda: |-
            id(current_multiply) = actual_value / id(current).raw_state;
        - number.set:
            id: current_factor
            value: !lambda "return id(current_multiply);"

improv_serial:

ota:
  - platform: esphome

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:
    ssid: "$friendly_name Hotspot"          # Fallback AP if station mode fails
    password: !secret ap_password

web_server:
  port: 80

captive_portal:

output:
  - platform: gpio
    id: relay_1
    pin: GPIO15
  - platform: gpio
    id: relay_2
    pin: GPIO4
  - platform: gpio
    id: led_1
    pin:
      number: GPIO2
      inverted: true
  - platform: gpio
    id: led_2
    pin:
      number: GPIO0
      inverted: true

switch:
  - platform: output
    output: relay_1
    name: "Outlet 1"
    id: cu9kw_socket_1
    icon: mdi:power-socket-uk
    on_turn_on:
      - output.turn_on: led_1
    on_turn_off:
      - output.turn_off: led_1

  - platform: output
    output: relay_2
    name: "Outlet 2"
    id: cu9kw_socket_2
    icon: mdi:power-socket-uk
    on_turn_on:
      - output.turn_on: led_2
    on_turn_off:
      - output.turn_off: led_2

binary_sensor:
  - platform: gpio
    id: button_1
    pin:
      number: GPIO16                            # Physical button pin
      mode:
        input: true
        pullup: false
      inverted: false
    on_press:
      - switch.toggle: cu9kw_socket_1

  - platform: gpio
    id: button_2
    pin:
      number: GPIO13
      mode:
        input: true
        pullup: true
      inverted: false
    on_press:
      - switch.toggle: cu9kw_socket_2

sensor:
  # Power Monitoring with calibration filters
  - platform: hlw8012
    model: BL0937
    sel_pin:
      number: GPIO12
      inverted: true
    cf_pin: GPIO5
    cf1_pin: GPIO14
    update_interval: 10s

    voltage:
      id: voltage
      name: "$friendly_name voltage"
      filters:
        - lambda: |-
            return x * id(voltage_multiply);

    power:
      id: power
      name: "$friendly_name power"
      filters:
        - lambda: |-
            return x * id(power_multiply);

    current:
      name: "$friendly_name current"
      id: current
      filters:
        - lambda: |-
            return x * id(current_multiply);

    energy:
      id: energy
      name: "$friendly_name energy"

  # Uptime & Wi-Fi
  - platform: uptime
    name: Uptime Sensor
    id: uptime_sensor
    update_interval: 60s
    on_raw_value:
      then:
        - text_sensor.template.publish:
            id: uptime_human
            state: !lambda |-
              int seconds = round(id(uptime_sensor).raw_state);
              int days    = seconds / (24 * 3600);
              seconds %= 24 * 3600;
              int hours   = seconds / 3600;
              seconds %= 3600;
              int minutes = seconds / 60;
              seconds %= 60;
              return (
                (days    ? to_string(days)    + "d " : "") +
                (hours   ? to_string(hours)   + "h " : "") +
                (minutes ? to_string(minutes) + "m " : "") +
                (to_string(seconds) + "s")
              ).c_str();

  - platform: wifi_signal
    name: "$friendly_name WiFi Signal Sensor"
    update_interval: 60s

  - platform: uptime
    name: "$friendly_name Uptime Sensor"

button:
  - platform: restart
    name: "Restart"
  - platform: safe_mode
    name: "Restart (Safe Mode)"
  - platform: factory_reset
    name: "Factory Reset"

text_sensor:
  - platform: wifi_info
    ip_address:
      name: "IP Address"
    ssid:
      name: "SSID"
    bssid:
      name: "BSSID"
    mac_address:
      name: "Mac Address"

  - platform: template
    name: Uptime Human Readable
    id: uptime_human
    icon: mdi:clock-start

# Calibration globals
globals:
  - id: voltage_multiply
    type: float
    restore_value: true
    initial_value: "0.3"                  # Default voltage multiplier
  - id: power_multiply
    type: float
    restore_value: true
    initial_value: "0.133"                # Default power multiplier
  - id: current_multiply
    type: float
    restore_value: true
    initial_value: "0.805"                # Default current multiplier
  - id: setupComplete
    type: bool
    restore_value: no
    initial_value: "false"                # Flag set after initial boot

# Expose calibration factors in Home Assistant
number:
  - platform: template
    name: "Voltage Calibration Factor"
    id: voltage_factor
    icon: mdi:sine-wave
    min_value: 0
    max_value: 10
    step: 0.001
    entity_category: diagnostic
    mode: box
    lambda: |-
      return id(voltage_multiply);
    set_action:
      lambda: |-
        id(voltage_multiply) = x;

  - platform: template
    name: "Power Calibration Factor"
    id: power_factor
    icon: mdi:flash
    min_value: 0
    max_value: 10
    step: 0.001
    entity_category: diagnostic
    mode: box
    lambda: |-
      return id(power_multiply);
    set_action:
      lambda: |-
        id(power_multiply) = x;

  - platform: template
    name: "Current Calibration Factor"
    id: current_factor
    icon: mdi:current-ac
    min_value: 0
    max_value: 10
    step: 0.001
    entity_category: diagnostic
    mode: box
    lambda: |-
      return id(current_multiply);
    set_action:
      lambda: |-
        id(current_multiply) = x;

Configuration bow published on

With credits to this thread given!

Thanks everyone again!

I might try my luck next with their power strip Smart 3G surge protected extension lead with Quad USB Charger | ML Accessories

Was looking forward to trying this out but it looks like they have revised their hardware and removed the pin holes on the esp chip making the reflash via pin far more difficult