Custom Lovelace cards that bring a full MeshCore mesh-radio companion experience into Home Assistant โ real-time chat, channel messaging, contact management, repeater telemetry, and more.
| File | Card type | Purpose |
|---|---|---|
meshcore-chat-card.js |
custom:meshcore-chat-card |
Full companion chat UI โ channels, DMs, contacts, node list |
meshcore-repeater-card.js |
custom:meshcore-repeater-card |
Live repeater stats with sparkline charts |
- meshcore-ha integration installed and configured in Home Assistant (HACS or manual).
- At least one MeshCore node connected (USB, BLE, or TCP).
- Home Assistant 2023.8 or newer.
- Open HACS in your Home Assistant sidebar.
- Go to Frontend.
- Click โฎ โ Custom repositories.
- Add this repository URL and set category to Lovelace.
- Click Download on MeshCore Companion Cards.
- Reload the browser.
HACS registers the resource URLs automatically. Skip to step 3 below.
Copy meshcore-chat-card.js (and optionally meshcore-repeater-card.js) to your HA config/www/ directory:
/config/www/meshcore-chat-card.js
/config/www/meshcore-repeater-card.js
Then register the resources. Go to Settings โ Dashboards โ โฎ (top-right menu) โ Resources and add:
| URL | Type |
|---|---|
/local/meshcore-chat-card.js |
JavaScript module |
/local/meshcore-repeater-card.js |
JavaScript module |
Or add to your configuration.yaml / ui-lovelace.yaml:
lovelace:
resources:
- url: /local/meshcore-chat-card.js
type: module
- url: /local/meshcore-repeater-card.js
type: moduleReload Lovelace (or hard-refresh the browser) after adding resources.
Use the visual editor (+ Add Card โ Custom: Meshcore Chat Card) or paste YAML directly:
type: custom:meshcore-chat-cardThe card auto-discovers your node from binary_sensor.meshcore_*_messages entities โ no manual configuration required for a basic setup.
type: custom:meshcore-chat-cardtype: custom:meshcore-chat-card
# Your own node's display name โ used to highlight your own messages.
# Must match the name your device broadcasts.
node_name: MyNode
# 6-character public-key prefix of your connected device.
# Auto-detected from binary sensor entity IDs; set manually if auto-detection
# fails or you have multiple devices.
device_prefix: b8f68f
# Config entry ID โ only needed when you have more than one MeshCore device.
entry_id: abc123def456
# Override or pre-configure channel names. Without this, channels are
# discovered automatically from the integration.
channels:
- idx: 0
name: Public
- idx: 1
name: "#local"
- idx: 2
name: "#emergency"
# Pin DM contacts by pubkey prefix. These appear in the sidebar even before
# any message has been received, and are synced to/from the device.
contacts:
- pubkey_prefix: fe3af51b24b9
name: Alice Pocket V2
- pubkey_prefix: a1b2c3d4e5f6
name: Bob HT
# Number of messages kept in memory per chat (default: 200).
max_messages: 200
# Hours of logbook history to load on first open (default: 24).
history_hours: 48
# Starting pane when the card loads: "chats" or "nodes" (default: "chats").
default_pane: chats
# Compact row spacing in the sidebar (default: false).
compact: false
# Card height โ any CSS length value (default: 600px).
# Examples: 600px | 80vh | min(80vh, 900px)
height: 700pxAll options above are also available through the Lovelace visual card editor โ click the pencil icon on any added card.
Click the gear icon (โ) in the sidebar header to open companion settings. These are stored in browser localStorage and override card YAML, so each browser/device can have its own preferences:
- Node name and device prefix
- History hours and message limit
- Default pane
- Channel list (add, rename, remove, apply to device)
- Contact list (add, remove, sync to device)
- Auto-discovered from
binary_sensor.meshcore_*_ch_*_messagesentities. - Additional channels fetched from the integration's
get_channelsservice. - Add a channel: click + in the sidebar or open Settings โ Channels.
- Apply to device: the Settings modal provisions new/renamed channels on the radio via
set_channel. - Channel names starting with
#are preserved as-is; plain names work too.
- Auto-discovered from
binary_sensor.meshcore_*_<pubkey>_messagesentities. - Pin permanent contacts via
contacts:config or Settings โ Contacts. - Add/remove contacts on the device from within the settings modal.
- Send: type and press
Enter(or the send button). - Reply: hover a message and click โฉ โ the reply bar appears with an
@[Name]prefix following MeshCore companion convention. - Multiline:
Shift+Enterinserts a newline; messages preserve line breaks. - Mention autocomplete: type
@to get a dropdown of contacts and nodes; navigate withโ โ, confirm withEnterorTab. - Channel autocomplete: type
#to get a dropdown of channels; selecting navigates to that channel. - Inline highlights:
@[Name]mentions are shown as blue chips;#channelreferences as green chips (clicking navigates to that channel). - Resend: when a channel message is not heard by any repeater (or a DM receives no ACK), a โบ Resend button appears on the bubble.
Each own message shows a status footer under the bubble:
| Status | Meaning |
|---|---|
โ sent |
Message dispatched to the radio |
๐ก sendingโฆ |
Waiting for repeater confirmation |
๐ก heard by N repeater(s) |
Confirmed reception with repeater list |
๐ก broadcast (no relays heard) |
Sent but no repeater reported hearing it |
โ delivered |
DM ACK received |
โ no ACK |
DM sent, no acknowledgement |
The hops toggle button (๐ก icon, top-right of chat header) collapses the status footer. When hidden, a compact โ in accent colour appears instead on confirmed messages.
Switch between Chats and Nodes using the tab bar at the top of the sidebar. The Nodes tab shows all discovered mesh nodes with online/offline status and a detail view on click.
At โค 640 px viewport width the sidebar and chat panel stack: the sidebar shows first; selecting a chat slides the panel in. A โน back button returns to the sidebar.
Set height: in YAML to any CSS length. Examples:
height: 700px # fixed pixels
height: 80vh # fraction of viewport
height: "min(80vh, 900px)" # cappedtype: custom:meshcore-repeater-cardAuto-discovers the first available repeater from sensor.meshcore_* entities.
type: custom:meshcore-repeater-card
# 10-hex pubkey prefix used in entity IDs, OR the repeater's friendly name.
# Omit to use the first discovered repeater.
repeater: b8f68f1234
# Card title override (default: repeater name from HA).
title: "Hilltop Repeater"
# History window for sparkline charts in hours (default: 24).
hours: 24
# Stat tiles to show (and their order). All available keys:
stats:
- battery_percentage
- bat
- uptime
- last_rssi
- last_snr
- tx_queue_len
- noise_floor
- nb_sent
- nb_recv
- airtime
# Sparkline charts to render (and their order).
charts:
- battery_percentage
- last_rssi
- last_snr
- airtime
- tx_queue_len
- noise_floor| Key | Label | Unit |
|---|---|---|
battery_percentage |
Battery | % |
bat |
Voltage | V |
uptime |
Uptime | โ |
airtime |
Airtime | min |
last_rssi |
RSSI | dBm |
last_snr |
SNR | dB |
tx_queue_len |
TX queue | โ |
noise_floor |
Noise floor | dBm |
nb_sent |
Packets sent | โ |
nb_recv |
Packets recv | โ |
sent_flood |
Flood sent | โ |
sent_direct |
Direct sent | โ |
recv_flood |
Flood recv | โ |
recv_direct |
Direct recv | โ |
full_evts |
Full events | โ |
direct_dups |
Direct dups | โ |
Both cards read the active Home Assistant theme automatically via CSS custom properties (--primary-color, --card-background-color, --primary-text-color, etc.). Light, dark, and custom themes all work without any configuration.
To override the chat bubble border-radius:
# In your theme YAML or card's style: override
# --bubble-radius controls chat bubble rounding (default: 18px)Card height and border-radius follow --ha-card-border-radius and --ha-card-box-shadow from the active theme.
- Confirm the
.jsfiles are in/config/www/. - Confirm the resource URLs are registered (Settings โ Dashboards โ Resources).
- Hard-refresh the browser (
Ctrl+Shift+R/Cmd+Shift+R).
- Check that the meshcore-ha integration is installed and your node is connected.
- Look for
binary_sensor.meshcore_*_messagesentities in Developer Tools โ States. - If entities exist but the card doesn't find them, set
device_prefix:manually to the 6-char prefix shown in the entity IDs.
- Increase
history_hours:(e.g.48). - The logbook must be enabled in HA. If the logbook integration is disabled, history won't load.
- History is loaded once per chat per page load; navigate away and back to reload.
- Ensure the meshcore-ha integration is connected (check the integration status in Settings โ Devices & Services).
- The
set_channelcommand requires firmware that supports API commands. - Check HA logs for
meshcoreerrors after clicking Apply.
- The card builds the contact list from
_discoveredContactsand_discoveredNodespopulated by the integration. If no contacts appear, verify the integration has discovered your mesh nodes (check the Nodes tab). - Ensure at least one advert has been received from the target node.
- The card waits up to 10 seconds for a delivery update from the integration. If none arrives, status clears to "broadcast (no relays heard)".
Set entry_id: in each card's YAML to the config entry ID of the device it should use. Find the entry ID in Settings โ Devices & Services โ Meshcore โ โฎ โ System information.
views:
- title: MeshCore
cards:
- type: custom:meshcore-chat-card
node_name: MyNode
height: 75vh
history_hours: 48
channels:
- idx: 0
name: Public
- idx: 1
name: "#local"
- type: custom:meshcore-repeater-card
repeater: b8f68f1234
hours: 24
charts:
- battery_percentage
- last_rssi
- last_snrThe automations/ directory contains optional bot automations that respond to channel commands.
Responds to es path on channel 2 with a formatted hop list showing each repeater in the message path.
Features:
- Emoji markers: ๐ก first hop, โณ middle hops, ๐ last hop
- Resolves repeater names from HA contact entities
- Configurable own-repeater name override
- Splits long paths across two messages (127-char limit per message)
- Per-user rate limit: 2 requests per minute
Before importing the automation, create a Text helper in HA to store rate-limit state:
- Go to Settings โ Devices & Services โ Helpers โ + Create Helper โ Text
- Set Name to
meshcore_path_ratelimit - Leave max length at 255 (or increase to 1024 in
configuration.yamlif you have many active users) - Save โ the entity ID will be
input_text.meshcore_path_ratelimit
Alternatively, add it to configuration.yaml:
input_text:
meshcore_path_ratelimit:
name: MeshCore Path Rate Limit
max: 1024Edit the two lines at the top of the reply_text template inside the automation:
{% set my_rpt_prefix = 'B37E15' %} # first 6 hex chars of your repeater's pubkey
{% set my_rpt_name = 'My Repeater' %} # friendly name to show instead of the pubkeySet my_rpt_prefix to '' to disable the override.
- meshcore-ha integration โ the HA integration these cards depend on
- meshcore-ha documentation โ full sensor, service, and automation reference
- MeshCore firmware โ the radio firmware