Google Icons for Android app: https://fonts.google.com/icons
SF Symbols for iOS app: SF Symbols - Apple Developer
Glad it got working!
Google Icons for Android app: https://fonts.google.com/icons
SF Symbols for iOS app: SF Symbols - Apple Developer
Glad it got working!
Soooo Close but…
I have everything ID wise correct, I can see the RESTful integration in devices and services, but when I select one of the items I receive the following.
This entity (‘sensor.centriconnect_sensor_tank_level’) does not have a unique ID, therefore its settings cannot be managed from the UI. See the documentation for more detail.
everything in the config.yaml looks identical to the yaml above, obviously with my own id information.
I am not sure what I am missing.
Thanks for the information on the icons.
See my reply to @philgrocks …still having issues.
Ah yes, I ran into that problem as well. I neglected to update when I fixed that problem… I’m soooo sorry!
So what is needed is to add unique id for each item. Here is the update code. See unique_id under each name.
Configuration for “mypropane” from “CentriConnect”
rest:
resource: “https://api.centriconnect.com/centriconnect/**user id goes here**/device/device id goes here/all-data”
scan_interval: 21600 #Every 6 hours as limited by CentriConnect
method: GET
params:
device_auth: “device auth goes here”
sensor:
- name: “MyPropane Level”
unique_id: “MyPropane_Level”
value_template: “{{ value_json [‘bf1b1b89-bba9-44f3-a337-2f2efe02a665’] [‘TankLevel’] | round(0) }}”
unit_of_measurement: “%”
- name: “MyPropane Next Time”
value_template: “{{ value_json [‘bf1b1b89-bba9-44f3-a337-2f2efe02a665’] [‘NextPostTimeIso’] }}”
- name: “MyPropane Last Time”
value_template: “{{ value_json [‘bf1b1b89-bba9-44f3-a337-2f2efe02a665’] [‘LastPostTimeIso’] }}”
- name: “MyPropane Battery Volts”
value_template: “{{ value_json [‘bf1b1b89-bba9-44f3-a337-2f2efe02a665’] [‘BatteryVolts’] | round(2) }}”
unit_of_measurement: “V”
- name: “MyPropane Solar Volts”
value_template: “{{ value_json [‘bf1b1b89-bba9-44f3-a337-2f2efe02a665’] [‘SolarVolts’] | round(2)}}”
unit_of_measurement: “V”
- name: “MyPropane Alert Status”
value_template: “{{ value_json [‘bf1b1b89-bba9-44f3-a337-2f2efe02a665’] [‘AlertStatus’] }}”
- name: “MyPropane Signal Quality”
value_template: “{{ value_json [‘bf1b1b89-bba9-44f3-a337-2f2efe02a665’] [‘SignalQualLTE’] | round(2) }}”
unit_of_measurement: “dB”
- name: “MyPropane Tank Size”
value_template: “{{ value_json [‘bf1b1b89-bba9-44f3-a337-2f2efe02a665’] [‘TankSize’] }}”
unit_of_measurement: “Gallons”
- name: “MyPropane Name”
value_template: “{{ value_json [‘bf1b1b89-bba9-44f3-a337-2f2efe02a665’] [‘DeviceName’] }}”
- name: “MyPropane Altitude”
value_template: “{{ value_json [‘bf1b1b89-bba9-44f3-a337-2f2efe02a665’] [‘Altitude’] | round(2) }}”
unit_of_measurement: “Meters”
ETA: OK , made some progress. with the help of an online editor I was able to get the formatting correct and after restarting everything I now have entities in the RESTful integration that are manageable!! of course I also have duplicate unmanageable entries too…not sure how to get rid of those. But a step in the right direction.
When creating a gauge card I am receiving the following

Am I correct in assuming this is because the data hasn’t been pulled from the unit yet? ![]()
I need to walk away from this for a little bit. if you code above works, then something is getting lost in the copy and paste.
Here is what I am seeing in config.yaml, and every time I try to fix something another thing goes red. I try to add the unique ids and get more errors
My lack of understanding of with yaml is probably a contributor
I really appreciate the assist, but I think I am going to curl up in the corner now.
I have run into odd characters getting into the code when I would cut and paste. I suspect this has happened to you.
What I had to do (and it is a pain) is to retype each line and delete the code that was pasted.
Hey LiQuid COOled can you provide a list of prerequisites? I have Custom Button Card and Custom Mushroom Card, but cannot get your code to show me anything ![]()
I am on vacation, but will assist you next week when I get back if you still need assistance.
hey @LiQuid_cOOled! If the info is here, I’ve missed it. How do you get the info from the Mopeka bridge into HA? Are you scraping a website or something more glamorous?
I think I missed something the script run but I am not getting data any time I add a Gauge I am getting “Entity is non-numeric: sensor.my_propane_level”
Fixed the errors…Fixed Used Chat GPT there was a typo with quotes
Could you share your icon somewhere?
Here is my card and code.
type: custom:mushroom-legacy-template-card
primary: >-
{{ [0, [((states('sensor.propane_tank_tank_weight') | float - 17) / 21 * 100),
100] | min] | max | round(0) }} %
secondary: ""
icon: mdi:propane-tank
entity: sensor.propane_tank_tank_weight
icon_color: |-
{% set bl = states('sensor.propane_tank_tank_weight') | int %}
{% if bl < 20 %} orange
{% elif bl < 27 %} blue
{% elif bl < 38 %} green
{% elif bl == 38 %} green
{% endif %}
card_mod:
style:
mushroom-shape-icon$: |
.shape {
--shape-color: none !important;
}
.: |
ha-state-icon {
animation: pulse 2s ease-in-out infinite;
stroke: white;
stroke-width: .4px;
}
ha-card {
background: none !important;
border: none !important;
}
visibility:
- condition: numeric_state
entity: sensor.propane_tank_tank_weight
below: 20
I think @LiQuid_cOOled helped me with animation. Thank you
Could you please share the icon image? I haven’t been able to do it here at all.
Super happy with this product so far. The base of the unit is magnetic but my tank is underground so I just attached some magnetic discs to the green plastic lid and it looks great. Here is my HA display. Simple but informative.
Configuration was super easy and Nick at Centri was very responsive.
A couple new sensors were recently added for tank temp in C and F (at bottom):
# configuration for "<ASSET_NAME>" from "CentriConnect"
rest:
scan_interval: 21600 # Every 6 hours (CentriConnect limit)
resource: "https://api.centriconnect.com/centriconnect/<ACCOUNT_UUID>/device/<DEVICE_UUID>/all-data"
method: GET
params:
device_auth: "<DEVICE_AUTH_CODE>"
sensor:
- name: "<ASSET_NAME> Level"
value_template: "{{ value_json['<DEVICE_UUID>']['TankLevel'] | round(0) }}"
unit_of_measurement: "%"
state_class: measurement
- name: "<ASSET_NAME> Next Time"
value_template: "{{ value_json['<DEVICE_UUID>']['NextPostTimeIso'] }}"
device_class: timestamp
- name: "<ASSET_NAME> Last Time"
value_template: "{{ value_json['<DEVICE_UUID>']['LastPostTimeIso'] }}"
device_class: timestamp
- name: "<ASSET_NAME> Battery Volts"
value_template: "{{ value_json['<DEVICE_UUID>']['BatteryVolts'] | round(2) }}"
unit_of_measurement: "V"
device_class: voltage
state_class: measurement
- name: "<ASSET_NAME> Solar Volts"
value_template: "{{ value_json['<DEVICE_UUID>']['SolarVolts'] | round(2) }}"
unit_of_measurement: "V"
device_class: voltage
state_class: measurement
- name: "<ASSET_NAME> Alert Status"
value_template: "{{ value_json['<DEVICE_UUID>']['AlertStatus'] }}"
- name: "<ASSET_NAME> Signal Quality"
value_template: "{{ value_json['<DEVICE_UUID>']['SignalQualLTE'] | round(2) }}"
unit_of_measurement: "dBm"
device_class: signal_strength
state_class: measurement
- name: "<ASSET_NAME> Tank Size"
value_template: "{{ value_json['<DEVICE_UUID>']['TankSize'] }}"
unit_of_measurement: "gal"
state_class: measurement
- name: "<ASSET_NAME> Name"
value_template: "{{ value_json['<DEVICE_UUID>']['DeviceName'] }}"
- name: "<ASSET_NAME> Altitude"
value_template: "{{ value_json['<DEVICE_UUID>']['Altitude'] | round(2) }}"
unit_of_measurement: "m"
device_class: distance
state_class: measurement
- name: "<ASSET_NAME> Temperature (°C)"
value_template: "{{ value_json['<DEVICE_UUID>']['DeviceTempCelsius'] | float | round(1) }}"
unit_of_measurement: "°C"
device_class: temperature
state_class: measurement
- name: "<ASSET_NAME> Temperature (°F)"
value_template: "{{ value_json['<DEVICE_UUID>']['DeviceTempFahrenheit'] | float | round(1) }}"
unit_of_measurement: "°F"
device_class: temperature
state_class: measurement
Has anyone using the Centri device worked out how to calculate consumption and store it in a way where it could be used on the energy dashboard?
I've been running a Centri MyPropane tank monitor on my 1,000-gallon tank and got it fully integrated into Home Assistant, including the Energy dashboard. Here's the complete setup in case it helps anyone else.
You need three credentials:
473fc198-1adf-4b9f-afde-4f3af9f2644e)The last two can be found on your device activation card that came with your device (the one that says "SAVE THIS CARD" at the top. Centri support ([email protected]) may be able to help if you've lost this card, but I had mine. They can also send you the API documentation if you need it - they're very helpful and responsive!
Create config/packages/propane.yaml (requires packages: !include_dir_named packages in your configuration.yaml). Replace the three placeholder values (YOUR_USER_ID, YOUR_DEVICE_ID, YOUR_DEVICE_AUTH) with your credentials and set tank_size to match your tank.
# CentriConnect Propane Tank Monitor
# API rate limit: 4 requests/device/day — scan_interval: 21600 matches exactly.
sensor:
- platform: rest
name: "Centri Tank Level"
unique_id: centri_tank_level
resource: "https://api.centriconnect.com/centriconnect/YOUR_USER_ID/device/YOUR_DEVICE_ID/all-data"
method: GET
params:
device_auth: "YOUR_DEVICE_AUTH"
scan_interval: 21600
unit_of_measurement: "%"
state_class: measurement
value_template: "{{ value_json['YOUR_DEVICE_ID']['TankLevel'] }}"
json_attributes_path: "$['YOUR_DEVICE_ID']"
json_attributes:
- AlertStatus
- Altitude
- BatteryVolts
- DeviceID
- DeviceName
- LastPostTimeIso
- Latitude
- Longitude
- NextPostTimeIso
- SignalQualLTE
- SolarVolts
- TankSize
- TankSizeUnit
- VersionHW
- VersionLTE
input_number:
propane_total_consumed_gal:
name: "Propane Total Consumed"
min: 0
max: 999999
step: 0.1
unit_of_measurement: "gal"
mode: box
icon: mdi:propane-tank-outline
propane_last_level_pct:
name: "Propane Last Known Level"
min: 0
max: 100
step: 0.1
unit_of_measurement: "%"
mode: box
icon: mdi:gauge
input_text:
propane_last_post_time:
name: "Propane Last Processed Post Time"
max: 50
icon: mdi:clock-check
template:
- sensor:
- name: "Propane Tank Remaining Gallons"
unique_id: propane_tank_remaining_gallons
unit_of_measurement: "gal"
state_class: measurement
icon: mdi:propane-tank
availability: "{{ has_value('sensor.centri_tank_level') }}"
state: >
{% set tank_size = state_attr('sensor.centri_tank_level', 'TankSize') | float(0) %}
{% set tank_level = states('sensor.centri_tank_level') | float(0) %}
{{ (tank_size * tank_level / 100) | round(1) }}
- name: "Propane Tank Last Updated"
unique_id: propane_tank_last_updated
icon: mdi:clock-outline
availability: "{{ state_attr('sensor.centri_tank_level', 'LastPostTimeIso') is not none }}"
state: >
{% set ts = state_attr('sensor.centri_tank_level', 'LastPostTimeIso') %}
{% if ts %}
{{ (ts | as_datetime).astimezone() | as_timestamp | timestamp_custom('%Y-%m-%d %H:%M') }}
{% else %}
Unknown
{% endif %}
- name: "Propane Tank Next Update"
unique_id: propane_tank_next_update
icon: mdi:clock-check-outline
availability: "{{ state_attr('sensor.centri_tank_level', 'NextPostTimeIso') is not none }}"
state: >
{% set ts = state_attr('sensor.centri_tank_level', 'NextPostTimeIso') %}
{% if ts %}
{{ (ts | as_datetime).astimezone() | as_timestamp | timestamp_custom('%Y-%m-%d %H:%M') }}
{% else %}
Unknown
{% endif %}
- name: "Propane Total Consumed Gallons"
unique_id: propane_total_consumed_gallons
unit_of_measurement: "gal"
state_class: total_increasing
icon: mdi:propane-tank-outline
state: "{{ states('input_number.propane_total_consumed_gal') | float(0) | round(1) }}"
# For Energy dashboard → Gas Consumption section.
# 1 US gallon liquid propane = 0.3649 CCF (industry standard at 60°F).
- name: "Propane Total Consumed CCF"
unique_id: propane_total_consumed_ccf
unit_of_measurement: "CCF"
device_class: gas
state_class: total_increasing
icon: mdi:fire
state: >
{{ (states('input_number.propane_total_consumed_gal') | float(0) * 0.3649) | round(3) }}
automation:
- id: centri_refresh_on_start
alias: "Refresh Centri Propane Sensor on Startup"
trigger:
- platform: homeassistant
event: start
action:
- delay:
seconds: 30
- service: homeassistant.update_entity
target:
entity_id: sensor.centri_tank_level
mode: single
- id: centri_track_consumption
alias: "Track Propane Consumption"
description: >
Fires on every new sensor reading. Deduplicates via LastPostTimeIso so
hourly polls or repeated restarts never double-count consumption.
trigger:
- platform: state
entity_id: sensor.centri_tank_level
not_to:
- unknown
- unavailable
action:
- variables:
new_level: "{{ trigger.to_state.state | float(0) }}"
new_post_time: "{{ state_attr('sensor.centri_tank_level', 'LastPostTimeIso') | string }}"
last_post_time: "{{ states('input_text.propane_last_post_time') }}"
prev_level: >
{% if trigger.from_state is not none
and trigger.from_state.state not in ['unknown', 'unavailable'] %}
{{ trigger.from_state.state | float(0) }}
{% else %}
{{ states('input_number.propane_last_level_pct') | float(0) }}
{% endif %}
- choose:
- conditions:
- condition: template
value_template: "{{ new_post_time != last_post_time and new_post_time not in ['None', 'unknown', ''] }}"
sequence:
- variables:
drop: "{{ [prev_level - new_level, 0] | max }}"
tank_size: "{{ state_attr('sensor.centri_tank_level', 'TankSize') | float(0) }}"
- choose:
- conditions:
- condition: template
value_template: "{{ drop > 0 and drop <= 30 }}"
sequence:
- service: input_number.set_value
target:
entity_id: input_number.propane_total_consumed_gal
data:
value: >
{{ (states('input_number.propane_total_consumed_gal') | float(0)
+ drop / 100 * tank_size) | round(2) }}
- service: input_text.set_value
target:
entity_id: input_text.propane_last_post_time
data:
value: "{{ new_post_time }}"
- service: input_number.set_value
target:
entity_id: input_number.propane_last_level_pct
data:
value: "{{ new_level }}"
mode: single
After restarting HA, go to Developer Tools → States, find sensor.centri_tank_level, and note its LastPostTimeIso attribute and current state. Then set the two helpers via Developer Tools → Services:
# input_number.set_value
entity_id: input_number.propane_last_level_pct
value: 57.2 # ← your current TankLevel %
# input_text.set_value
entity_id: input_text.propane_last_post_time
value: "2026-05-18 17:01:44.000" # ← your current LastPostTimeIso
This tells the automation "I've already processed this reading" so the first real consumption event is recorded correctly.
Go to Settings → Dashboards → Energy → Gas consumption and add sensor.propane_total_consumed_ccf.
HA's gas section only accepts m³, ft³, or CCF - not gallons directly. The conversion used here (0.3649 CCF/gallon) is the industry-standard figure for US liquid propane vaporised at 60°F.
The API returns TankLevel as a raw percentage with no mention of temperature correction in the documentation. Propane expands roughly 1% per 10°F, so across a large seasonal temperature swing you may see a few percentage points of variance that doesn't represent actual consumption. The gallon figures should be treated as estimates rather than billing-precise measurements.
The Centri device posts data ~4 times a day. Each posting has a unique LastPostTimeIso timestamp that doesn't change no matter how many times you poll the API afterward. The input_text.propane_last_post_time helper stores the timestamp of the last reading that was actually processed. When the automation fires, it compares the incoming timestamp against the stored one — if they match, the response is a duplicate and everything is skipped. This means you can safely lower scan_interval without risking double-counted consumption.
@royf007 published a HACS custom card that displays a nice animated horizontal tank with color-coded fill level. Install via HACS → Custom repositories, then:
yaml
type: custom:ha-centri-propane-tank-card
entity: sensor.centri_tank_level
tank_size: 1000 # your tank capacity in gallons