Create a custom enitity/sensor from a webhook JSON payload

Hi Kenneth,
I think you should be able to a little math to achieve this.
My Jinja sucks, but something like this might get you started, although I haven’t tested it.

sensor:
  - platform: mqtt
    name: "iSpindel Batteri Prosent"
    state_topic: "brew/ferment/tilt/battery"
    value_template: "{{ (states('sensor.ispindel_batterylevel' | float  - 3.0 ) / (4.3 - 3.0) * 100) | round(0) }}"
    unit_of_measurement: "%"

Good luck and happy brewing!
Cheers,
Michael.

Thank you for guiding me in a direction :slight_smile: I found one bracket to much, but still it gives me wrong output. I get -231 % :slight_smile: But my head does not manage to see the next step…

sensor:
  - platform: mqtt
    name: "iSpindel Batteri Prosent"
    state_topic: "brew/ferment/tilt/battery"
    value_template: "{{ (states('sensor.ispindel_batterylevel') | float - 3.0 / (4.3 - 3.0) * 100) | round(0) }}"
    unit_of_measurement: "%"
    value_template: >-
      {% set full = 4.3 %}
      {% set empty = 3.0 %}
      {% set level = states('sensor.ispindel_batterylevel')|float %}
      {{ [100, [0, (level - empty) * (100 / (full - empty))]|max]|min|int }}

Or you could do it hardcoded on one line:

    value_template: "{{ [100, [0, (states('sensor.ispindel_batterylevel')|float - 3) * (100 / (4.3 - 3))]|max]|min|int }}"

This restricts it to 0% min, 100% max, so if the sensor does spike to 4.4V, it’ll still show 100%.

Also, add device_class: battery and you get an appropriately-charged battery icon for free.

Thank you Troon. This advanced code gives me 0%. The other gives me -227%. I dont get it

You need a range of 1.3V to cover 100%, starting at 3.0V. So you need to subtract 3.0 to get the offset and multiply by 100/1.3 to get the scaling.

The previous code fell victim to rules of order (BODMAS or various other acronyms). You had:

(x - 3.0 / (4.3 - 3.0) * 100)

The division operator is higher priority than the subtract, so you were getting:

(x - (3.0 / (4.3 - 3.0) * 100))

whereas you wanted:

((x - 3.0) / (4.3 - 3.0) * 100)

My template is equivalent to this corrected line, with just a little tweak to clamp it between 0 and 100%.

Thank you again. It was working after the next update from the webhook. Sorry for bother you more. iSpindel

1 Like

Hi. Could you provide your code for this chart? Have you also one for gravity?

Sorry not replying!
Here’s my code - careful of cut/paste indents etc… this is obviously dependant on variable names too.

type: 'custom:apexcharts-card'
header:
  show: true
  title: iSpindel Temperature & Battery
apex_config:
  chart:
    zoom:
      enabled: true
    height: 450
  yaxis:
    - min: 18
      max: 24
      opposite: true
      seriesName: Temp
      decimalsInFloat: 1
      name: Temp
      title:
        text: Temp
    - min: 3.5
      max: 4.3
      opposite: false
      seriesName: Battery
      decimalsInFloat: 2
      name: Battery
      title:
        text: Battery
    - min: 1
      max: 1.07
      opposite: false
      seriesName: Gravity
      decimalsInFloat: 3
      name: Gravity
      title:
        text: Gravity
    - show: false
  stroke:
    width: 1
series:
  - entity: sensor.ispindle_temp
    name: Temp
    group_by:
      func: avg
      duration: 8min
    float_precision: 1
    curve: smooth
  - entity: sensor.ispindle_batterry
    name: Battery
    group_by:
      func: avg
      duration: 12min
    float_precision: 1
    curve: smooth
  - entity: sensor.ispindle_gravity
    name: Gravity
    group_by:
      func: avg
      duration: 30min
    float_precision: 3
    curve: smooth
  - entity: sensor.beer_template
    type: area
    curve: stepline
    name: Heater
graph_span: 48h
y_axis_precision: 3

And here’s the code for the mqtt integration to pull the data into sensors from the mqtt server and also enable the chart to display the status of the heat pad.
A simple automation turns that smart switch on at 22C and off at 23C

sensor:
  - platform: mqtt
    name: "Ispindle Tilt"
    state_topic: "ispindel/Batt_test/tilt"
    unit_of_measurement: '°'
    force_update: true
    
sensor 2:
  - platform: mqtt
    name: "Ispindle Temp"
    state_topic: "ispindel/Batt_test/temperature"
    unit_of_measurement: 'C'
    force_update: true
    
sensor 3:
  - platform: mqtt
    name: "Ispindle Batterry"
    state_topic: "ispindel/Batt_test/battery"
    unit_of_measurement: 'V'
    force_update: true
    
sensor 4:
  - platform: mqtt
    name: "Ispindle Gravity"
    state_topic: "ispindel/Batt_test/gravity"
    unit_of_measurement: ''
    force_update: true

sensor 5:
  - platform: mqtt
    name: "Ispindle RSSI"
    state_topic: "ispindel/Batt_test/RSSI"
    unit_of_measurement: ''
    force_update: true
    
        
sensor 7:
  - platform: template
    sensors:
      beer_template:
        friendly_name: "Beer Matt on/off"
        value_template: >-
          {% if is_state('switch.00655508840d8eb5a394', 'on') %}
            1
          {% else %}
            0
          {% endif %}

Hi,

I have to use 2 sensors to get battery %

  1. to extract the data frm a json payload
- platform: mqtt
  state_topic: "application/14/device/a84041f181830356/event/up"
  name: Thyroxine Battery
  value_template: '{{ value_json["object"]["BAT_V"] }}'

and then to covert to battery %

    thyroxine_battery_percentage:
      entity_id: sensor.battery
      value_template: "{{ [100, [0, (states('sensor.thyroxine_battery')|float -2 ) * (100 / (3.6 - 2.4))]|max]|min|int }}"
      device_class: battery
      unit_of_measurement: "%"

The range of the batteries is 3.6V to around 2.4V

This gives me a battery % of 96%, however this is closer to around 55% in reality (current reading is 3.06V)

Can anyone spot anything awry in my calcs? Or any other optimisation tips tricks would be great too!

Many thanks!

At a glance, should that -2 actually be a -2.4, like this?

    thyroxine_battery_percentage:
      entity_id: sensor.battery
      value_template: "{{ [100, [0, (states('sensor.thyroxine_battery')|float -2.4 ) * (100 / (3.6 - 2.4))]|max]|min|int }}"
      device_class: battery
      unit_of_measurement: "%"
1 Like