Skip to content

Instantly share code, notes, and snippets.

@jonmunson
Created January 13, 2026 14:20
Show Gist options
  • Select an option

  • Save jonmunson/10b7e9953ecb8c582faf82f4f4b55a19 to your computer and use it in GitHub Desktop.

Select an option

Save jonmunson/10b7e9953ecb8c582faf82f4f4b55a19 to your computer and use it in GitHub Desktop.
FoxESS home battery SoC (state of charge) pushed from Home Assistant to an Awtrix custom app over MQTT. The automation reads the battery’s SoC and infers charging/discharging/idle from FoxESS charge/discharge power, then publishes a matching icon plus a progress bar so the clock shows a live battery % at a glance.
alias: Awtrix Home Battery Charge (FoxESS)
description: Publishes FoxESS battery SoC to an AWTRIX 3 Custom App via MQTT
mode: single
trigger:
- alias: Matrix turned on
platform: state
entity_id: light.awtrix_1c7378_matrix
to: "on"
- alias: Battery sensors change
platform: state
entity_id:
- sensor.battery_soc
- sensor.battery_charge
- sensor.battery_discharge
condition: []
action:
# Wait briefly so SoC is available (useful when the matrix just turned on)
- wait_template: >
{{ states('sensor.battery_soc') not in ['unknown','unavailable','none',''] }}
timeout: "00:00:10"
continue_on_timeout: true
# Only publish if SoC looks valid
- condition: template
value_template: >
{% set raw = states('sensor.battery_soc') | replace('%','') | trim %}
{{ raw not in ['unknown','unavailable','none',''] and (raw | float(-1)) >= 0 }}
- service: mqtt.publish
data:
topic: awtrix_1c7378/custom/batterycharge
qos: 0
retain: false
payload: >-
{# -----------------------
SoC parsing (handles "49%" or 49 or 0.49)
----------------------- #}
{%- set raw_soc = states('sensor.battery_soc') | replace('%','') | trim -%}
{%- set v = raw_soc | float(0) -%}
{%- set charge = (v*100 if v <= 1 else v) | round(0) | int -%}
{%- set charge = [0, [charge, 100] | min] | max -%}
{# -----------------------
Derive mode from FoxESS power flow:
- sensor.battery_charge (kW)
- sensor.battery_discharge (kW)
----------------------- #}
{%- set chg = states('sensor.battery_charge') | float(0) -%}
{%- set dis = states('sensor.battery_discharge') | float(0) -%}
{%- set thresh = 0.05 -%} {# kW noise threshold #}
{%- if chg > thresh and chg >= dis -%}
{%- set mode = "Charge" -%}
{%- elif dis > thresh and dis > chg -%}
{%- set mode = "Discharge" -%}
{%- else -%}
{%- set mode = "Idle" -%}
{%- endif -%}
{# -----------------------
Icon selection (LaMetric icon IDs)
----------------------- #}
{%- if mode == "Charge" -%}
{%- if charge > 85 -%}
{%- set icon = 32047 -%}
{%- elif charge > 69 -%}
{%- set icon = 32049 -%}
{%- elif charge > 51 -%}
{%- set icon = 32050 -%}
{%- elif charge > 34 -%}
{%- set icon = 32051 -%}
{%- elif charge > 17 -%}
{%- set icon = 32052 -%}
{%- else -%}
{%- set icon = 32053 -%}
{%- endif -%}
{%- elif mode == "Discharge" -%}
{%- if charge > 85 -%}
{%- set icon = 32059 -%}
{%- elif charge > 69 -%}
{%- set icon = 32058 -%}
{%- elif charge > 51 -%}
{%- set icon = 32057 -%}
{%- elif charge > 34 -%}
{%- set icon = 32056 -%}
{%- elif charge > 17 -%}
{%- set icon = 32055 -%}
{%- else -%}
{%- set icon = 32054 -%}
{%- endif -%}
{%- else -%} {# Idle/Standby #}
{%- if charge > 90 -%}
{%- set icon = 13735 -%}
{%- elif charge > 70 -%}
{%- set icon = 13732 -%}
{%- elif charge > 40 -%}
{%- set icon = 13731 -%}
{%- elif charge > 10 -%}
{%- set icon = 13725 -%}
{%- else -%}
{%- set icon = 13734 -%}
{%- endif -%}
{%- endif -%}
{"text":"{{ charge }} %","icon":"{{ icon }}","progress":{{ charge }}}
@jonmunson
Copy link
Author

ICON DOWNLOAD NOTES

AWTRIX 3 Custom Apps can display LaMetric icons by ID, but the icon needs to be available on the device. Typical workflow:

  1. Open your AWTRIX web UI
  2. Go to “Icons”
  3. Enter the icon ID → Preview → Download/Save to the device

This automation uses the following icon IDs:

CHARGING ICONS (mode == "Charge")

  • 32047 (SoC > 85)
  • 32049 (SoC 70–85)
  • 32050 (SoC 52–69)
  • 32051 (SoC 35–51)
  • 32052 (SoC 18–34)
  • 32053 (SoC 0–17)

DISCHARGING ICONS (mode == "Discharge")

  • 32059 (SoC > 85)
  • 32058 (SoC 70–85)
  • 32057 (SoC 52–69)
  • 32056 (SoC 35–51)
  • 32055 (SoC 18–34)
  • 32054 (SoC 0–17)

IDLE/STANDBY ICONS (mode == "Idle")

  • 13735 (SoC > 90)
  • 13732 (SoC 71–90)
  • 13731 (SoC 41–70)
  • 13725 (SoC 11–40)
  • 13734 (SoC 0–10)

Notes / tips

  • If an icon doesn’t show, it usually means it hasn’t been downloaded to the AWTRIX yet (or the ID is wrong).
  • You can swap any of these IDs for others from the LaMetric icon library, as long as you download them to the device first.
  • If your battery “flickers” between Charge/Discharge at low power, increase the threshold used in the automation (e.g., from 0.05 kW to 0.10 kW).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment