ESPHome Bluetooth Tracker for Nutridays KT630LB kitchen scale

Product: Nutridays KT630LB Bluetooth Kitchen Scale

Brief Description:
ESPHome configuration for Nutridays KT630LB Bluetooth kitchen scale. The device connects via BLE to read weight measurements in real-time. Scale has 1g resolution and sends data packets with 24-bit weight values. ESP32-C3 automatically connects when scale is detected, reads weight data, and publishes to Home Assistant with 1-second throttle. Includes connection status monitoring and automatic disconnect when scale goes out of range.

esphome:
  name: kitchenscale
  friendly_name: kitchenscale

esp32:
  board: esp32-c3-devkitm-1 
  framework:
    type: esp-idf

logger:
  level: INFO

api:
  encryption:
    key: "YOUR_ENCRYPTION_KEY"

ota:
  - platform: esphome
    password: "YOUR_OTA_PASSWORD"

wifi:
  ssid: "YOUR_WIFI_SSID"
  password: "YOUR_WIFI_PASSWORD"  
  manual_ip:
    static_ip: 192.168.x.x
    gateway: 192.168.x.x
    subnet: 255.255.255.0
    dns1: 192.168.x.x
  output_power: 10dB
  fast_connect: true
  passive_scan: false

globals:
  - id: kitchenscale_weight_raw
    type: int
    restore_value: no
    initial_value: '0'
  - id: kitchenscale_ble_connected
    type: bool
    restore_value: no
    initial_value: 'false'

esp32_ble_tracker:
  scan_parameters:
    interval: 1200ms
    window: 400ms
    active: false

ble_client:
  - mac_address: "XX:XX:XX:XX:XX:XX"
    id: kitchen_scale
    auto_connect: false
    on_connect:
      then:
        - lambda: |-
            id(kitchenscale_ble_connected) = true;
    on_disconnect:
      then:
        - lambda: |-
            id(kitchenscale_ble_connected) = false;

interval:
  - interval: 3s
    then:
      - text_sensor.template.publish:
          id: kitchenscale_status
          state: !lambda |-
            if (id(kitchenscale_ble_connected)) {
              return "Connected";
            } else {
              return "Waiting";
            }
      - lambda: |-
          static uint64_t last_connect_attempt = 0;
          uint64_t now = millis();
          
          if (!id(kitchen_scale)->connected() && 
              id(kitchenscale_detected).state &&
              (now - last_connect_attempt > 10000)) { 
            last_connect_attempt = now;
            id(kitchen_scale)->connect();
          }
          
          if (id(kitchen_scale)->connected() && 
              !id(kitchenscale_detected).state) {
            static uint64_t disconnect_timer = 0;
            if (disconnect_timer == 0) {
              disconnect_timer = now;
            } else if (now - disconnect_timer > 5000) {  
              id(kitchen_scale)->disconnect();
              disconnect_timer = 0;
            }
          } else {
            static uint64_t disconnect_timer = 0;
            disconnect_timer = 0; 
          }

sensor:
  - platform: ble_client
    type: characteristic
    name: "Kitchen Scale Raw Data"
    id: kitchen_scale_data
    internal: true
    ble_client_id: kitchen_scale
    service_uuid: '0000ffb0-0000-1000-8000-00805f9b34fb'
    characteristic_uuid: '0000ffb2-0000-1000-8000-00805f9b34fb'
    notify: true
    lambda: |-
      if (x.size() >= 20 && x[0] == 0xAC && x[1] == 0x40) {
        uint32_t weight_raw = ((uint32_t)x[4] << 16) | ((uint32_t)x[5] << 8) | x[6];
        id(kitchenscale_weight_raw) = weight_raw;
        float weight_grams = (float)weight_raw / 1000.0;
        id(kitchen_weight).publish_state(weight_grams);
      }
      return {};

  - platform: template
    id: kitchen_weight
    name: "Kitchen Scale Weight"
    icon: "mdi:scale"
    unit_of_measurement: "g"
    accuracy_decimals: 0
    device_class: weight
    state_class: measurement
    filters:
      - throttle: 1s
    lambda: 'return id(kitchenscale_weight_raw) / 1000.0;'

binary_sensor:
  - platform: status
    name: "Status"

  - platform: ble_presence
    mac_address: "XX:XX:XX:XX:XX:XX"
    name: "Kitchenscale Detected"
    id: kitchenscale_detected

text_sensor:
  - platform: template
    id: kitchenscale_status
    name: "Kitchenscale Status"
    icon: 'mdi:bluetooth'
    lambda: |-
      if (id(kitchenscale_ble_connected)) {
        return {"Connected"};
      } else {
        return {"Waiting"};
      }
  
  - platform: wifi_info
    ip_address:
      name: "IP Address"
    ssid:
      name: "SSID"
    mac_address:
      name: "Mac Address"
2 Likes