πŸ”˜ Piotras Smart Button

:radio_button: Piotras Smart Button

A high-performance button card for Home Assistant β€” Most cards go silent after calling a service. This one tells you it worked.

:sparkles: Features

  • Visual Editor β€” full GUI with tabs: General, Size, Background, Icon, Text, Layout, Slider & Power, Filters, Actions, Service. No manual YAML needed.
  • 9-Grid Layout System β€” place Icon, Name, and State badge independently across a 3Γ—3 matrix.
  • Adaptive Auto-Sliders β€” smart detection of Brightness, Color Temp, Volume, Cover Position, Fan Speed. Zero configuration required.
  • Dynamic Backgrounds β€” solid color, 2/3-color gradients, or full-resolution background images.
  • Smart Filter Engine β€” CSS filters (brightness, saturation, grayscale) applied automatically per ON/OFF state.
  • Service Countdown β€” animated SVG circle or progress bar after call-service, with optional card blockade.
  • Power Monitoring β€” real-time consumption bar with configurable pulse warning threshold.
  • Font Styles β€” 4 text presets for Name and State labels.
  • Advanced Action Engine β€” Tap, Double-Tap, and Hold, optimized for both mobile and desktop.
  • Visual Editor Full GUI β€” General, Size, Background, Icon, Text, Layout, Slider & Power, Filters, Actions, Service tabs. No YAML required.

:compass: Navigation Mode

:light_bulb: Light & Auto-Dimmer Slider


:electric_plug: Socket & Power Monitoring


:scroll: Script Button


:speaker_high_volume: Media Player


:gear: Installation

Method 1: Via HACS (Recommended)

  1. Click the button below to automatically add the repository to your HACS:
Open your Home Assistant instance
  1. Click Add in the pop-up window.
  2. Once the repository page opens, click Download.
  3. After downloading, do a Hard reload of your browser.

Method 2: Manual Installation

  1. Download this repository as a ZIP file and extract it.
  2. Inside your Home Assistant config/www/ directory, create a new folder named piotras-smart-button.
  3. Copy the compiled files (from dist/ folder) into config/www/piotras-smart-button/.
  4. Go to Settings β†’ Dashboards β†’ Resources.
  5. Click Add Resource and enter:
/local/piotras-smart-button/piotras-smart-button-loader.js?v=1.0.0
  • Resource type: JavaScript Module
  1. Hard reload your browser (Ctrl+Shift+R).
2 Likes

You should also upload the source code to github, not just the dist files :eyes:

Thanks for the suggestion. Currently, I’m focusing on refining the stable dist version to ensure the best user experience. The full source code will be made available alongside the official HACS release. If the official Home Assistant HACS submission process requires it, the repository will be updated accordingly. For now, my priority is delivering a polished final product. Please stay tuned for the official HACS launch.

Release v1.1.0

Editor Fix β€” Config State Display + Minor Card Fixes

Fixed editor incorrectly showing default values instead of actual YAML config. Toggles, number and text fields now correctly reflect saved state. Minor card fix: removed hardcoded widths on service bar and slider zones β€” now fully responsive to card_width setting.

An example of how the script works
Animation

Still no /src available?

v1.2.0

Person & Device Tracker support

  • Control Zone now shows last state change time (HH:MM) for person and device_tracker entities
  • Bar icon uses mdi:home / mdi:walk colored by icon_color_on (home) and icon_color (away)

Battery monitoring

  • Dynamic main card icon auto-adjusted to charge level (mdi:battery-10 β†’ mdi:battery)
  • Color bar in Control Zone: red β†’ yellow β†’ green
  • Optional entity_battery_state for charging detection (charging / discharging / full / not_charging)
  • Card turns ON when charging, OFF otherwise
  • ⚑ suffix when charging

Thermostat control

  • Control Zone renders βˆ’ / + temperature buttons with 0.5Β° step
  • State badge shows current room temperature instead of ON/OFF
  • Card turns ON when hvac_action is heating or cooling
  • Red OFF label when thermostat is fully off

Dual icon mode

  • New icon_on option β€” separate icon for ON state
  • Battery ignores icon and icon_on β€” always uses dynamic battery icon

Control Zone scaling

  • All Control Zone content (labels, icons, sliders, bars) scales proportionally with slider_height using √(height/26) β€” smooth, non-linear growth

New options

  • slider_label_color β€” single color variable for all Control Zone labels and icons
  • entity_battery_state β€” optional battery charging state entity
  • icon_on β€” alternative icon for ON state

Visual Editor improvements

  • Editor detects entity domain automatically
  • Slider & Power tab shows only relevant options per entity type
  • icon and icon_on fields hidden for battery (auto-dynamic)
  • name_on / name_off fields hidden for climate (state badge is automatic)
  • Battery Icon Tip shown in Icon tab

I’ve put together a live preview of all my card assets. If you’re looking for icons or graphics for your buttons, feel free to check it out:

:eye: View Smart Button Assets

First guides for the card are now available. Hope someone finds them useful!

:rocket: What's New?

:crown: custom_states_on β€” Universal Priority

The custom_states_on option now has the absolute highest priority across the entire card system. It completely overrides the built-in logic for battery, climate, alarm_control_panel, vacuum, and all other domains. If defined, it always wins β€” no exceptions.

:glowing_star: custom_states_labels β€” Major Upgrade

:1234: Numeric matching with operators and ranges

Labels can now be dynamically matched using comparison operators and numerical ranges instead of just exact text:

custom_states_labels:
  "<10": "Cold"
  "10-25": "Comfortable"
  ">25": "Hot"
  • Supported operators: >, <, >=, <= and min-max ranges (including wrap-around ranges like 22-0 for overnight hours).
  • Highest priority: custom_states_labels is now checked before any domain-specific labels (media_player, light, climate, fan, cover). If a match is found, it wins β€” while name_on/name_off act as a fallback..

:chart_increasing: Percentage-based matching

For domains where the main entity state is always on/off but the actual "level" is stored in an attribute, values are automatically converted to a percentage (0–100):

  • light β€” matches against brightness converted to %
  • fan β€” matches against percentage speed
  • cover β€” matches against current_position

Example for light brightness:

custom_states_labels:
  off: "Off"
  "<10": "Atmospheric"
  "10-40": "Low"
  "40-80": "Bright"
  ">80": "Max"

:thermometer: Second value line (value2) for climate entities

When you define custom_states_labels for a climate entity, a second smaller label will automatically appear below the current temperature.

  • Matching priority: hvac_action β†’ state (hvac_mode) β†’ preset_mode..
custom_states_labels:
  off: ""
  heating: "Heating"
  idle: "Idle"
  eco: "Eco"
  comfort: "Comfort"

The font size defaults to state_size - 5px. You can override it using the value2_size parameter.

:sun_behind_small_cloud: Second value line (value2) for weather entities

The same mechanism now works for weather cards β€” matching is done directly against the temperature attribute.

custom_states_labels:
  "<5": "Cold: heavy coat"
  "5-15": "Cool: jacket"
  "15-25": "Comfortable: light layer"
  ">25": "Hot: t-shirt"

:alarm_clock: Greeting label for clock mode (entity: on.clock)

When custom_states_labels is defined for the built-in clock mode, a greeting label appears right above the digits and updates live every single second β€” no page reload needed!

entity: on.clock
custom_states_labels:
  "0-5": "Night... πŸŒ™"
  "5-9": "Good morning! β˜•"
  "9-17": "Have a great day! πŸ‘‹"
  "17-22": "Good evening! πŸŒ†"
  "22-0": "Good night! ✨"

:input_latin_letters: Auto line-wrapping

Long labels now automatically wrap within the card boundaries, so there's no more need for manual <br> tags (though manual <br> tags still work if you want to force a break at a specific point).

:high_voltage: max_watts β€” Now Accepts Entity ID

The max_watts parameter now accepts either a fixed number or a live Entity ID (e.g., a power sensor). The value is read live from the sensor's state.

max_watts: sensor.socket_max_power
# or as before:
max_watts: 2000

:memo: Important Configuration Notes

  • All changes are fully backward compatible β€” your existing configurations will work without any modifications.
  • :warning: Standard YAML Rule: Any keys using > or < operators MUST be quoted (e.g., ">25", "<10"), otherwise the YAML parser will fail.
  • For operator-based keys using > or >=, list them from highest to lowest value β€” the first match wins.
  • For < or <= keys, list them from lowest to highest for the exact same reason.

:open_file_folder: English Documentation & Repository

While the detailed markdown guides in the docs folder are currently available in Polish (working on the English translation soon!), you can find the direct links and the full project right here:


:star: Enjoying this project?

If you are using this card and like my work, please consider leaving a Star on GitHub! :glowing_star:
(You can find the repo link posted earlier in this thread).
It only takes a single click, but it gives me huge motivation to keep developing this project and bringing new features. Thanks! :raising_hands: