Calibrate Linear Filter using a Global Variable?

I’m creating a load cell based scale and would like to calibrate the scale to a known weight via the internal web server or from HA without having to upload new code each time.

From what I understand this would require using either a global variable or reading the value from HA and neither is allowed for a calibrate linear filter.
Screen Shot 2022-02-15 at 10.41.32 AM
As you can see in the code below, this global variable is float.

Has anyone been able to use a variable or a sensor as a calibration data point?

Is there a way to call the calibrate_linear function from a lambda that can use global variables?


  name: test-scale
  friendly_name: Test Scale
  entity_name: test_scale

# Map Raw sensor values to Kg
  # Begin initial setup by retrieving the values below by evaluating the raw values with loads of known mass.
  # Measure four weights from 0 Kg to the highest known mass without exceeding the load cell.
  # Note: A bigger difference between mass results in higher scale resolution.
  # Mass in Kg used for calibration
  mass_0_kg: '0'
  mass_1_kg: '5' # heaviest weight without exceeding the load cell
  # Raw sensor value for above mass
  mass_0_raw: '172500'
  mass_1_raw: '1247000'

  name: $name
  platform: ESP32
  board: wemos_d1_mini32

  type: LAN8720
  mdc_pin: GPIO23
  mdio_pin: GPIO18
  clk_mode: GPIO17_OUT
  phy_addr: 0
  power_pin: GPIO5
  use_address: $ip_address

  disabled: true

  password: !secret api_password
  reboot_timeout: 0s

  password: !secret ota_password

  baud_rate: 0  # Disable UART logging
    hx711: ERROR
  port: 80


  - id: tare_value
    type: float
    restore_value: yes
    initial_value: '0'
  - id: manual_tare_flag
    type: bool
    restore_value: no
    initial_value: 'false'


# Switch used to initiate a manual tare
  - platform: template
    id: tare_action_switch
    name: "$friendly_name Manual Tare Action"
    lambda: |-
      return id(manual_tare_flag);
      - lambda: |-
          id(tare_value) = $mass_0_raw - id(cell_raw).state ;
      - switch.turn_off: tare_action_switch
      - lambda: |-
          id(manual_tare_flag) = false;
# Switch Virtual Restart
  - platform: restart
    name: "$friendly_name Restart"
    id: restart_switch         


# mass map template sensors
  - platform: template
    id: current_mass_0_raw
    name: "$friendly_name Map $mass_0_kg Kg"
    lambda: |-
      return $mass_0_raw;
    update_interval: 1days

  - platform: template
    id: current_mass_1_raw
    name: "$friendly_name Map $mass_1_kg Kg"
    lambda: |-
      return $mass_1_raw;
    update_interval: 1days

# Tare template sensor
  - platform: template
    id: current_tare
    name: "$friendly_name Current Tare"
    lambda: |-
      return id(tare_value);
    update_interval: 1s
      - or:
        - throttle: 1min
        - delta: 1
# Cell Raw to 0 Kg deviation template sensor
  - platform: template
    id: zero_kg_deviation
    name: "$friendly_name 0 Kg / Raw"
    lambda: |-
      return $mass_0_raw - id(cell_raw).state;
    update_interval: 1s

# Raw ADC Reading
  - platform: hx711
    name: "$friendly_name Raw"
    id: cell_raw
    internal: False
    dout_pin: GPIO14
    clk_pin: GPIO33
    gain: 128
    # unit_of_measurement: kg
    accuracy_decimals: 0
    update_interval: 0.2s
    # filter out the top five values and send the nineteenth highest value in the dataset
      - quantile:
          window_size: 25
          send_every: 25
          send_first_at: 25
          quantile: .8
        - lambda: 'id(cell_kg).publish_state(x);'

# Raw ADC Temperature Compensated to Kg
  - platform: template 
    id: cell_kg
    name: "$friendly_name Measured Mass"
    internal: False
      # apply tare
      - lambda: 'return x + id(tare_value);'
      # apply rough calibration
      - calibrate_linear:
          - $mass_0_raw -> $mass_0_kg
          - $mass_1_raw -> $mass_1_kg
      # map values below 0.1 to 0 (to decrease value changes due to random fluctuation)
      - lambda: |-
          if (x <= 0.1) {
            return 0.0;
          } else {
            return x;
      - sliding_window_moving_average:
          window_size: 3
          send_every: 1
      - throttle: 5s
    unit_of_measurement: kg
    accuracy_decimals: 3
    update_interval: 0.2s
1 Like

I’ve been doing stuff with load cells recently, and calibrating is a pain.

If you’re calibrating with zero weight and a single known weight only (so 2 readings) then you can probably perform the maths yourself to convert your raw reading into kg, and not use the calibrate_linear function. This would allow you to use variables in a template / lambda

You can also store the variables in globals, and use the restore_from_flash option so the variable survives restarts.

Hope that helps.

Im trying to do the exact same thing… smooth out the hx711 spikes and create a “recalibrate” function that will adjust the reference points for the “calibrate_linear” function.
Did you ever find a way to do it?

1 Like

This has a manual/auto tare function.

Unfortunately not.

Did you find any solution to this?

Haven’t, but also haven’t looked into it. Hard coded it and moved on.

Try this piece of code:

  initial_zero_value: "-59553"

  - id: initial_zero
    type: float
    restore_value: yes
    initial_value: '${initial_zero_value}'

- calibrate_linear:
    - ${initial_zero_value}.0 -> 0
1 Like

Will the substitutions initial_zero_value variable change and be permanent with the change of the global variable initial_zero?