A Lovelace card for Home Assistant focused on TP-Link client monitoring and quick router controls.
⭐ Found it useful? Please star the repo to support development and help others discover it.
📊 Rich Data Visualization
- Live Client Table: Real-time mapping directly from router
device_trackerentities. - Smart Formatting: Human-readable formatting for traffic, link rates, duration, and signal quality.
- Colorized Metrics: Optional color scales for TX/RX and Up/Down speeds for quick visual scanning.
- Advanced Tooltips: Hover over Up/Down speeds for a detailed utilization bar, bandwidth load percentage, adaptive transfer units, and current/max Mbps.
🎛️ Interactive Controls & Actions
- Router Dashboard: Header featuring local URL, public IP, CPU/MEM summary, and quick actions.
- Customizable Actions: Row-level and header-level actions with flexible rendering modes (
icon,name,icon_name). - Hold-to-Confirm: 1-second hold requirement for destructive actions to prevent accidental clicks.
- Visual State Feedback: Explicit state coloring for toggle actions.
- Haptic Feedback: Built-in vibration feedback on supported mobile/webview environments during interactions.
🖱️ Advanced Navigation & Shortcuts
- Shift + Click Entity Access: Hold
Shiftand click on metric cells (like speed, traffic, signal) to instantly open the underlying Home Assistant entity's more-info dialog. - Name-Cell Navigation: Click a device name to open its entity more-info (
tplink_router/tplink_deco) or device page (omada). - Inline Shortcuts: Quick device shortcut icons directly in the Name column.
🎨 Flexible & Responsive Layout
- Powerful
column_layout: Define exact column order, custom headers, and per-columnmax_width(px,%,vw,clamp(), etc.). - Sticky Columns: Pin columns to the start or end of the table with elegant edge shadow indicators during horizontal scroll.
- Responsive Design: Header and action layouts adapt perfectly across desktop, tablet, and mobile screens.
- Headless Modes: Hide the header or filter sections for a compact, table-only dashboard view.
🔍 Search, Filter & Sort
- Fast Search: Real-time search across name, IP, hostname, and MAC address.
- Regex Support: Use
/pattern/syntax in the search box for advanced filtering. - Quick Filters: Compact dropdowns for Band (2.4G/5G/6G), Connection (WiFi/Wired/IoT/Guest), and Status.
- Multi-Sort:
Shift + clickon column headers to sort by multiple columns simultaneously.
🌍 Global & Developer Features
- i18n Support: Automatic Home Assistant locale selection (English, Turkish, etc.).
- Diagnostics Export: Built-in, redacted JSON export for easy bug reporting and troubleshooting.
tplink_router:
tplink_deco:
omada / tplink_omada:
Header variants (hide_header / hide_filter_section options):
Headless layout: the filter row stays visible while the header is hidden.
Headless + no filter layout: both header and filter row are hidden for a compact table-only card.
- Supported integrations:
home-assistant-tplink-router(tplink_router)ha-tplink-deco(tplink_deco)ha-omada(omada)- Home Assistant Core
tplink_omada(tplink_omada)
Support level summary:
tplink_router: full supporttplink_deco: high supportomada: high supporttplink_omada: high support
Detailed matrix: docs/integration-support.md
-
tplink_router:- Full client table mapping from router tracker attributes.
-
tplink_deco:- Client/deco table mapping from
device_tracker.*entities. - Supports
connection_typeandinterfacemapping. - Upload/download speed values are normalized automatically.
- Client/deco table mapping from
-
Omada (
omada/tplink_omada):- Device-based row mapping with controller client data.
- Per-row actions (
actionscolumn) from matchedswitch.*/button.*entities. - Header action target selector for infrastructure devices.
- Metric/entity bridge for Omada-only fields with Shift+click cell info.
- Extra Omada columns:
downloaded,uploaded,snr,powerSavedeviceType,deviceModel,deviceFirmware,deviceStatus
Notes:
- Available actions and sensors depend on model, firmware, and integration-exposed entities.
- If an action cannot be matched safely, it is hidden by design.
- Integration-specific attributes are parsed with safe fallbacks. Missing fields never crash the card and are rendered as
—.
- Open HACS.
- Add this repository as a Dashboard custom repository.
- Install HA TP-Link Router Card.
- Verify resource exists:
/hacsfiles/ha-tplink-router-card/ha-tplink-router-card.js- Type:
JavaScript Module
Download the latest release asset and place it under:
/config/www/ha-tplink-router-card/ha-tplink-router-card.js
CLI example:
mkdir -p /config/www/ha-tplink-router-card
wget -O /config/www/ha-tplink-router-card/ha-tplink-router-card.js \
https://github.com/hepter/ha-tplink-router-card/releases/latest/download/ha-tplink-router-card.jsAdd resource (YAML):
resources:
- url: /local/ha-tplink-router-card/ha-tplink-router-card.js?v=1
type: moduleUI path:
- Settings → Dashboards → Resources → Add Resource
Minimal:
type: custom:tplink-router-cardGeneric example:
type: custom:tplink-router-card
title: My Router
entry_id: <config_entry_id>
speed_unit: MBps
txrx_color: true
updown_color: true
show_hidden_entities: false
header_action_render: icon
row_action_render: icon
shift_click_underline: true
hide_header: false
hide_filter_section: false
default_filters:
band: all
connection: all
status: all
upload_speed_color_max: 1000
download_speed_color_max: 100
column_layout:
- key: name
fixed: start
max_width: 140px
- key: status
- key: connection
- key: band
- key: ip
- key: mac
- key: hostname
- key: down
- key: upCross-integration safe baseline column_layout:
column_layout:
- key: name
- key: status
- key: connection
- key: band
- key: ip
- key: mac
- key: hostname
- key: down
- key: upIntegration-specific extra keys:
# tplink_router
- packetsSent
- packetsReceived
- tx
- rx
- online
- traffic
- signal
# omada / tplink_omada
- downloaded
- uploaded
- snr
- powerSave
- actions
# tplink_deco / omada / tplink_omada metadata
- deviceType
- deviceModel
- deviceFirmware
- deviceStatusFor YAML users, define the full order with column_layout.
tplink_router (recommended)
type: custom:tplink-router-card
entry_id: <tplink_router_entry_id>
column_layout:
- key: name
fixed: start
- key: status
- key: connection
- key: band
- key: ip
- key: mac
- key: hostname
- key: packetsSent
- key: packetsReceived
- key: down
- key: up
- key: tx
- key: rx
- key: online
- key: traffic
- key: signaltplink_deco (recommended)
type: custom:tplink-router-card
entry_id: <tplink_deco_entry_id>
column_layout:
- key: name
fixed: start
- key: status
- key: connection
- key: band
- key: ip
- key: mac
- key: hostname
- key: down
- key: up
- key: deviceType
- key: deviceModel
- key: deviceFirmware
- key: deviceStatusomada / tplink_omada (recommended)
type: custom:tplink-router-card
entry_id: <omada_entry_id>
column_layout:
- key: name
fixed: start
- key: status
- key: connection
- key: band
- key: ip
- key: mac
- key: hostname
- key: down
- key: up
- key: online
- key: downloaded
- key: uploaded
- key: traffic
- key: signal
- key: snr
- key: powerSave
- key: deviceType
- key: deviceModel
- key: deviceFirmware
- key: deviceStatus
- key: actionsOptions:
title: Card title.entry_id: Config entry to use. Selected from editor.speed_unit:MBps(default) orMbpsfor Up/Down columns.txrx_color: Enable colorized TX/RX speed levels.updown_color: Enable colorized upload/download speeds.show_hidden_entities: Show hidden switch/button entities in action areas. Defaultfalse.header_action_render: Header action button style:icon | name | icon_name. Defaulticon. Works across all supported integrations when header actions exist.row_action_render: Row action button style:icon | name | icon_name. Defaulticon. Currently effective for Omada row actions (omada/tplink_omada).shift_click_underline: Show Shift+click underline hints for entity-clickable cells (currently Omada-only visual behavior).hide_header: Hide the header area.hide_filter_section: Hide the filter section.default_filters: Optional fixed default filters applied on every page load.band:all | 2g | 5g | 6gconnection:all | wifi | wired | iot | gueststatus:all | online | offline
upload_speed_color_max: Upload color scale max in Mbps. Default1000.download_speed_color_max: Download color scale max in Mbps. Default100.column_layout: Primary column definition with order, sticky columns, and optional header override:key(required): Column key.fixed(optional):start | end(default is none, or omit the field).name(optional): Header label override.max_width(optional): CSSmax-widthvalue for that column.- Number-only values are treated as px (
100=>100px). - You can use values like
100px,35%,22vw,10vh,18rem,clamp(180px, 30vw, 420px).
- Number-only values are treated as px (
- Example:
column_layout: - key: name fixed: start max_width: 160px - key: status - key: ip - key: actions
- Header override example:
column_layout: - key: down name: Download - key: up name: Upload
columns(deprecated): legacy string-array format, kept only for backward compatibility.
Rules:
- Column order follows
column_layoutorder. - Only columns valid for the selected integration domain are rendered.
- Sticky behavior is applied only to columns marked with
fixed: start|end. - Sticky columns use edge shadow indicators during horizontal scroll.
- Non-sticky columns are never width-limited by sticky column rules.
column_layout.max_widthis injected directly as each column'smax-widthstyle.- Legacy
columnsis still accepted and auto-migrated internally tocolumn_layout. - If
default_filtersis set, it overrides localStorage filter restore on every reload. hide_filter_sectionworks well withdefault_filtersfor fixed filtered dashboards.
header_action_render applies to header actions for all supported integrations.
row_action_render applies to row-level actions, currently available for omada / tplink_omada.
- Display mode:
header_action_render: icon | name | icon_namerow_action_render: icon | name | icon_name
- Label source:
- In
name/icon_namemodes, labels come from entity display names. - If you want cleaner labels, rename entities in Home Assistant.
- Quick path: Shift + click an action button to open entity more-info, then edit the display name.
- In
- Hide unwanted actions:
- Open the target action entity in Home Assistant and set it as hidden (
Visibleoff). - Keep
show_hidden_entities: false(default) to exclude hidden actions from the card. - Set
show_hidden_entities: trueonly if you explicitly want hidden actions to appear. - This affects header actions generally, and row actions where row actions are supported.
- Open the target action entity in Home Assistant and set it as hidden (
Editor preview:
When reporting a bug, attach a diagnostics dump:
- Open the card.
- Double-click the card title.
- Click the download icon.
- Attach the JSON file to your issue.
Export behavior:
- Output is redacted only.
- Sensitive values are masked (IP/MAC/URL/token-like values and sensitive keys).
- Includes card UI state (search text, filters, sorts) to reproduce behavior.
- Includes size/depth protection and truncation markers for very large payloads.
- For your security, review the file before attaching it to a public issue.
For local end-to-end testing with real integration setup flows, a virtual device lab is included:
virtual_modems/tplink_router_be230(fortplink_router)virtual_modems/tplink_deco_x50(fortplink_deco)virtual_modems/omada_controller(shared byomadaandtplink_omada)
See virtual_modems/README.md for setup and run commands.
- Missing entries: ensure the integration is installed and the selected
entry_idis correct. - Empty table with a valid
entry_id: check quick filters (All / 2G / 5G / 6G,All / WiFi / Wired / IoT / Guest,All / Online / Offline). - Missing metadata/tooltips: some routers/integrations do not expose full router details.
- No action icons: action entities may be unsupported, unavailable, or intentionally filtered for safety.
See CONTRIBUTING.md.
MIT. See LICENSE.





