Lovelace: Versatile Swiss Army Knife Custom Card

Hi,
I am using the storage mode.
I belive the only gap I have now is the ui-lovelace.yaml setup.
Added here more details: [Question] Install Challanges · Issue #171 · AmoebeLabs/swiss-army-knife-card · GitHub
What’s the best option to add those while using the storage mode ?

PS: The only option it seems to merge all the SAK declutering templates and add them to each dasboard using the Raw Editor :frowning:

Hi all

I have been testing with the swiss army knive card and I love it

But I keep on having an issue, for which I need help
I created 2 cards (see below, based on the examples).

Scherm­afbeelding 2022-11-05 om 12.06.42

This works but every time I reload/refresh/start the page I get an error (see below)
Scherm­afbeelding 2022-11-05 om 12.07.20
To solve this I go to the swiss army knife examples page I installed during the setup and load the SAKE11-M3 page and then go back to my pages and it works again.
But this is not how it suppose to work of course.

Any help or tips are more than welcome.
I tried to contact the creator of the swiss army knife card, but I had no response so far.

Many thanks in advance

Rien du Pre

Hi for some reason the gauge does not display the data, however when I click on the gauge it loads the entity history and the data is there.

Gauge just displays nothing.

Code below

#
# View			: view-sake5
# Project   : Home Assistant / Swiss Army Knife custom card.
# Repository: https://github.com/AmoebeLabs/swiss-army-knife-card
#
# Author    : Mars @ AmoebeLabs.com
# 
# License   : CC BY-SA, https://creativecommons.org/licenses/by/4.0/
#
# -----
# Description:
# SAK Example #5, with two cards: Car Dashboard Flat/Material Design and one in 
# Neumorphic Design.
#
# Data sources:
# - Met weather integration: replace below weather.zoefdehaas with your own entity!
#
# Templates used:
# - none, both cards are hard-core YAML
#
# Card #1, 5a
# ============
# - Flat design.
#
# Card #2, 5b:
# ============
# - Neumorphic Design
# - Shows how the unit of measurement can be positioned below the state.
#   The default is after the state.
#
#   Uom can can be positioned with:
#   - end for the default position after the state
#   - top for above the state
#   - bottom for below the state.
#
# Refs:
#   
###############################################################################

title: SAKE5
path: sake5
panel: false
theme: 'NM - Gonsboro'
cards:
#------------------------------------------------------------------------------
- type: vertical-stack
  cards:
# =================================
    - type: horizontal-stack
      cards:
        #
        # Example 5a::
        #
        #######################################################################

        - type: 'custom:swiss-army-knife-card'
          entities:
            - entity: sensor.pooltemperature
              attribute: temperature
              decimals: 1
              name: '1T: Met Weather'
              area: 'pool'
              unit: '°C'
              icon: mdi:thermometer
            - entity: sensor.pooltemperature
              attribute: humidity
              decimals: 0
              unit: '%'
              icon: mdi:water-percent
            - entity: sensor.pooltemperature
              attribute: pressure
              decimals: 0
              unit: 'hPa'
              icon: mdi:gauge

          aspectratio: 2/1

          disable_card: false

          dev:
            debug: false
            ts: true
            
          layout:
            styles:
              card:
              toolsets:
                filter: url(#sak-drop-1)
            toolsets:
              # ==============================================================================
              - toolset: temperature
                # name: temperature
                position:
                  cx: 100
                  cy: 50
                  # Uncomment the next line, and be surprised what different scaling in x/y
                  # can do with your visualisation!
                  # scale_y: 0.4
                tools:
                  - type: 'area'
                    id: 0
                    entity_index: 0
                    position:
                      cx: 50
                      cy: 80
                    styles:
                      area:
                        font-size: 7.2em

                  - type: 'name'
                    id: 0
                    entity_index: 0
                    position:
                      cx: 50
                      cy: 95
                    styles:
                      name:
                        font-size: 6em
                        text-anchor: middle

                  - type: 'segarc'
                    id: 0
                    entity_index: 0
                    position:
                      cx: 50
                      cy: 50
                      start_angle: -130
                      end_angle: 130
                      width: 7
                      radius: 45
                    scale:
                      min: -20
                      max: 40
                      offset: -4.5
                    show:
                      scale: true
                      style: 'colorstops'
                    segments:
                      colorlist:
                        gap: 1
                        colors:
                          - '#5e4fa2'
                          - '#3288bd'
                          - '#66c2a5'
                          - '#abdda4'
                          - '#e6f598'
                          - '#fee08b'
                          - '#fdae61'
                          - '#f46d43'
                          - '#d53e4f'
                          - '#9e0142'
                      colorstops:
                        gap: 1
                        colors:
                          -30: 'white'
                          -20: '#5e4fa2'
                          -10: '#3288bd'
                          0: '#66c2a5'
                          05: '#abdda4'
                          10: '#e6f598'
                          15: '#fee08b'
                          20: '#fdae61'
                          25: '#f46d43'
                          30: '#d53e4f'
                          35: '#9e0142'
                    styles:
                      foreground:
                        fill: var(--theme-gradient-color-01)
                      background:
                        fill: var(--primary-background-color)
                        filter: url(#is-1)

                  - type: 'state'
                    id: 0
                    entity_index: 0
                    position:
                      cx: 50
                      cy: 40
                    styles:
                      state:
                        text-anchor: middle
                        font-size: 15em
                        fill: var(--primary-text-color)

                  - type: 'icon'
                    id: 0
                    entity_index: 0
                    position:
                      cx: 50
                      cy: 60
                      align: center
                      icon_size: 18.5
                    styles:
                      icon:
                        color: var(--primary-text-color)
                        fill: var(--primary-text-color)

              # ==============================================================================
              - toolset: humi
                position:
                  cx: 50
                  cy: 50
                tools:
                  - type: 'segarc'
                    id: 1
                    entity_index: 1
                    position:
                      cx: 50
                      cy: 50
                      start_angle: -130
                      end_angle: 20
                      width: 5
                      radius: 45
                    scale:
                      min: 0
                      max: 100
                    show:
                      scale: true
                      style: 'colorstops'
                      labelstops: false
                    segments:
                      colorstops:
                        gap: 1
                        colors:
                          00: 'var(--theme-gradient-color-02)'
                          35: 'DarkSeaGreen'
                          65: 'PowderBlue'
                    styles:
                      foreground:
                        fill: var(--theme-gradient-color-02)
                      background:
                        fill: var(--primary-background-color)
                        filter: url(#is-1)

                  - type: 'state'
                    id: 0
                    entity_index: 1
                    position:
                      cx: 35
                      cy: 40
                    styles:
                      state:
                        text-anchor: middle
                        font-size: 10em
                        fill: var(--primary-text-color)

                  - type: 'icon'
                    id: 0
                    entity_index: 1
                    position:
                      cx: 35
                      cy: 60
                      align: center
                      icon_size: 18.5
                    styles:
                      icon:
                        color: var(--primary-text-color)
                        fill: var(--primary-text-color))

              # ==============================================================================
              - toolset: pressure
                position:
                  cx: 150
                  cy: 50
                tools:
                  - type: 'segarc'
                    id: 1
                    entity_index: 2
                    position:
                      cx: 50
                      cy: 50
                      start_angle: 130
                      end_angle: -20
                      width: 5
                      radius: 45
                    scale:
                      min: 930
                      max: 1050
                    show:
                      scale: true
                      style: 'colorstops'
                    segments:
                      colorstops:
                        gap: 1
                        colors:
                          980: 'lightgrey'
                          990: 'var(--theme-gradient-color-01)'
                          1020: 'var(--theme-gradient-color-05)'
                    styles:
                      foreground:
                        fill: var(--theme-gradient-color-03)
                      background:
                        fill: var(--primary-background-color)
                        filter: url(#is-1)

                  - type: 'state'
                    id: 0
                    entity_index: 2
                    position:
                      cx: 65
                      cy: 40
                    styles:
                      state:
                        text-anchor: middle
                        font-size: 10em
                        fill: var(--primary-text-color)

                  - type: 'icon'
                    id: 0
                    entity_index: 2
                    position:
                      cx: 65
                      cy: 60
                      align: center
                      icon_size: 18.5
                    styles:
                      icon:
                        color: var(--primary-text-color)
                        fill: var(--primary-text-color)

#################################################################################

    - type: horizontal-stack
      cards:
        #
        # Example 5b:: Neumorphic version of 5a.
        #
        #######################################################################

        - type: 'custom:swiss-army-knife-card'
          entities:
            - entity: sensor.pooltemperature
              attribute: temperature
              decimals: 1
              name: '11T: met.no Weather'
              area: 'pool'
              unit: '°C'
              icon: mdi:thermometer
            - entity: sensor.pooltemperature
              attribute: humidity
              decimals: 0
              unit: '%'
              icon: mdi:water-percent
            - entity: sensor.pooltemperature
              attribute: pressure
              decimals: 0
              unit: 'hPa'
              icon: mdi:gauge

          aspectratio: 2/1

          disable_card: false

          dev:
            debug: false
            
          layout:
            styles:
              card:
              toolsets:
                filter: url(#nm-1)
            toolsets:

             # ==============================================================================
              - toolset: humi
                position:
                  cx: 50
                  cy: 50
                tools:
                  # Neumorphic Disc
                  - type: circle
                    entity_index: 0
                    position:
                      cx: 50
                      cy: 50
                      radius: 45
                    styles:
                      circle:
                        fill: var(--primary-background-color)

                  - type: 'segarc'
                    id: 1
                    entity_index: 1
                    position:
                      cx: 50
                      cy: 50
                      start_angle: -212.5
                      end_angle: 32.5
                      width: 5
                      radius: 40
                    scale:
                      min: 0
                      max: 100
                    show:
                      scale: true
                      style: 'colorstops'
                      labelstops: false
                    segments:
                      colorstops:
                        gap: 1
                        colors:
                          00: 'var(--theme-gradient-color-02)'
                          35: 'DarkSeaGreen'
                          65: 'PowderBlue'
                    styles:
                      foreground:
                        fill: var(--theme-gradient-color-02)
                      background:
                        fill: var(--cs-theme-default-darken-15)
                        filter: url(#is-1)

                  - type: 'icon'
                    id: 0
                    entity_index: 1
                    position:
                      cx: 38
                      cy: 32.5
                      align: center
                      icon_size: 18.5
                    styles:
                      icon:
                        color: var(--primary-text-color)
                        fill: var(--primary-text-color)
                        opacity: 0.7
                        filter: url(#is-1)

                  - type: 'state'
                    id: 0
                    entity_index: 1
                    position:
                      cx: 38
                      cy: 50
                    show:
                      uom: bottom
                    styles:
                      state:
                        text-anchor: middle
                        font-size: 12.5em
                        font-weight: bolder
                        fill: var(--primary-text-color)
                        opacity: 0.7
                        filter: url(#is-1)

              # ==============================================================================
              - toolset: pressure
                position:
                  cx: 150
                  cy: 50
                tools:
                  # Neumorphic Disc
                  - type: circle
                    entity_index: 0
                    position:
                      cx: 50
                      cy: 50
                      radius: 45
                    styles:
                      circle:
                        fill: var(--primary-background-color)

                  - type: 'segarc'
                    id: 1
                    entity_index: 2
                    position:
                      cx: 50
                      cy: 50
                      start_angle: 212.5
                      end_angle: -32.5
                      width: 5
                      radius: 40
                    scale:
                      min: 930
                      max: 1050
                    show:
                      scale: true
                      style: 'colorstops'
                    segments:
                      colorstops:
                        gap: 1
                        colors:
                          980: 'lightgrey'
                          990: 'var(--theme-gradient-color-01)'
                          1020: 'var(--theme-gradient-color-05)'
                    styles:
                      foreground:
                        fill: var(--theme-gradient-color-03)
                      background:
                        fill: var(--cs-theme-default-darken-15)
                        filter: url(#is-1)

                  - type: 'icon'
                    id: 0
                    entity_index: 2
                    position:
                      cx: 62
                      cy: 32.5
                      align: center
                      icon_size: 18.5
                    styles:
                      icon:
                        color: var(--primary-text-color)
                        fill: var(--primary-text-color)
                        opacity: 0.7
                        filter: url(#is-1)

                  - type: 'state'
                    id: 0
                    entity_index: 2
                    position:
                      cx: 62
                      cy: 50
                    show:
                      uom: bottom
                    styles:
                      state:
                        text-anchor: middle
                        font-size: 12.5em
                        font-weight: bolder
                        fill: var(--primary-text-color)
                        opacity: 0.7
                        filter: url(#is-1)

              # ==============================================================================
              - toolset: temp
                position:
                  cx: 100
                  cy: 50
                tools:
                  # Neumorphic Disc
                  - type: circle
                    entity_index: 0
                    position:
                      cx: 50
                      cy: 50
                      radius: 45
                    styles:
                      circle:
                        fill: var(--primary-background-color)
                        filter: url(#nm-1)
                  
                  - type: 'segarc'
                    id: 0
                    entity_index: 0
                    position:
                      cx: 50
                      cy: 50
                      start_angle: -140
                      end_angle: 140
                      width: 5
                      radius: 40
                    scale:
                      min: -20
                      max: 40
                    show:
                      scale: true
                      style: 'colorstops'
                    segments:
                      colorlist:
                        gap: 1
                        colors:
                          - '#5e4fa2'
                          - '#3288bd'
                          - '#66c2a5'
                          - '#abdda4'
                          - '#e6f598'
                          - '#fee08b'
                          - '#fdae61'
                          - '#f46d43'
                          - '#d53e4f'
                          - '#9e0142'
                      colorstops:
                        gap: 1
                        colors:
                          -30: 'white'
                          -20: '#5e4fa2'
                          -10: '#3288bd'
                          0: '#66c2a5'
                          05: '#abdda4'
                          10: '#e6f598'
                          15: '#fee08b'
                          20: '#fdae61'
                          25: '#f46d43'
                          30: '#d53e4f'
                          35: '#9e0142'
                    styles:
                      foreground:
                        fill: var(--theme-gradient-color-01)
                      background:
                        fill: var(--cs-theme-default-darken-15)
                        filter: url(#is-1)
                      scale:
                        filter: url(#nm-1)

                  - type: 'icon'
                    id: 0
                    entity_index: 0
                    position:
                      cx: 50
                      cy: 30
                      align: center
                      icon_size: 18.5
                    styles:
                      icon:
                        color: var(--primary-text-color)
                        fill: var(--primary-text-color)
                        opacity: 0.7
                        filter: url(#is-1)

                  - type: 'state'
                    id: 0
                    entity_index: 0
                    position:
                      cx: 50
                      cy: 50
                    show:
                      uom: bottom
                    styles:
                      state:
                        text-anchor: middle
                        font-size: 15em
                        fill: var(--primary-text-color)
                        opacity: 0.7
                        font-weight: bolder
                        filter: url(#is-1)

               # ==============================================================================
              - toolset: text-stuff
                position:
                  cx: 100
                  cy: 50
                tools:
                  - type: 'area'
                    id: 0
                    entity_index: 0
                    position:
                      cx: 50
                      cy: 85
                    styles:
                      area:
                        font-size: 7.2em

I’m trying to get the example battery card to work with proper colors while I’m using a theme (NM-Gonsboro) different from the one it’s designed for (Material 3 theme D06, TealBlue). Does the custom card take the “theme:” attribute at all so I can apply D06 just for this card? And, yes, I do have this theme in my ‘themes’ directory - “\127.0.0.1\config\themes\m3-d06-tealblue.yaml”

So far had no luck with this:

          - type: horizontal-stack
            cards:        
              - type: 'custom:swiss-army-knife-card'
                theme: m3-d06-tealblue
                entities:
                
                  - entity: sensor.galaxy_watch5_j73x_battery_level
                    name: 'Watch'
                
                layout:
                  template:
                    name: sak_layout_fce_sensor2
                    variables:
                      - sak_layout_sensor_name_above_state: false
                      - sak_layout_sensor_colorstops_template: colorstops_battery_level
                      - sak_layout_sensor_icon_style: colorstops
                      - sak_layout_sensor_segarc_style: colorstops
                      - sak_layout_sensor_segarc_scale_max: 100

First of all, thank you @AmoebeLabs for your contribution to this community! I’m loving working with your card (more of a graphical framework). It took me about four hours to build some templates and my first card, then about 20 minutes to build the rest of the cards for my first dashboard page.

I have a question about the user_actions. I can find examples of drag_action and tap_action and those are self explanatory. What I’m hoping to be able to do is capture hold or double-tap actions as is possible with other cards, both native and custom. Are these actions possible with SAK?

Second, in Example 2 I see the menu icon on the first card seems to be overloaded with multiple actions.

                    user_actions:
                      tap_action:
                        haptic: success
                        actions:
                          - action: more-info
                          - action: call-service
                            service: light.toggle
                            service_data:
                              entity_id: light.livingroom_light_duo_right_light
                          - action: call-service
                            service: light.toggle
                            service_data:
                              entity_id: light.livingroom_light_front_right_light

In this example, does a tap_action activate each of the three actions defined with one tap? I looked but was unable to find any description on how to use the user_actions or what configurations were available.

Thank you for any assistance!

I am trying to follow the tutorials to get a glimpse of what I can achieve. Unfortunatelly, from the first attempt, I encounter two problems:

  • icon is not displayed if not explicitely declared. I looked into ‘icon’ attribute of the entity and it’s there.
  • name and stateare not properly aligned. They start from center instead to be positioned on the center.

Am I doing something wrong? Below is a copy paste of tutorial #1 slighty modified:

I was able to solve this issue. I could not find a way to capture hold or double-tap actions but to put multiple actions on the same toolset I simply configured tap actions on multiple ‘items’ on the card.

In this case, I’m using a group entity to show the status of a light group. Tapping on the icon produces a navigation action to a sub-view that shows all the lights. I put a power icon in the upper-right corner of the card and tapping that icon will toggle the state of the group.
image

@rumbu13 could you post the code for your card so we can see the full details?
Hint: please use the ‘preformatted text’ button in the toolbar.

From what I can see in the screenshot you posted, you may need a text-anchor: statement in the styles section.

styles:
  state:
    font-size: 15em
    text-anchor: middle

Do the same thing for the name tool.

If that doesn’t have the desired effect, please post your code.

1 Like

I’m trying to enhance the responsiveness of my dashboard on different devices and looking into using a grid layout. Using the Layout-Card from HACS I can create the grid template and then span columns for cards that should be wider than others. The issue I’m having is the card that renders in the span is taller than the other card(s) on the row.
image
(The entities in these cards are meaning less, just playing with the layout currently.)

This is a 3-column grid. The first card (Lighting) has aspectratio: 1/1. When the second card is also 1/1 it is the same height as the first. When I change it to aspectratio: 2/1 and add the grid-column: span 2 statement the height of the card is slightly taller.

I believe this is because the card that spans more than one column is also spanning the space that is usually between the columns so the card is slightly wider than two columns.

I’m still playing with it but if anyone has any suggestions on how to handle this, please let me know.

Code Example
          # Climate Card
          - type: custom:swiss-army-knife-card
            aspectratio: 2/1
            view_layout: 
              grid-column: span 2
            disable_card: false
            entities:
              # Workshop Temperature Sensor
              - entity: sensor.workshop_temperature_sensor
                name: "Workshop Temperature"
            layout:
              toolsets:
                - toolset: sensor-segarc
                  ...

Many Thanks!

Thanks, this solved it! As I said, I just copied the code from the tutorial example (Tutorial #1, Part 1 - Swiss Army Knife Card), there is no text-anchor there.

1 Like

Hi,

First my best wishes for 2023!

I tried to customize the sake12 dashboard with environment cards.
Everything is working fine, except my sensor data is not visible!
My data from my entities are there if I click on one of the circles!
Any idea what is wrong?

#
# View			: view-sake12-ani-m3
# Project   : Home Assistant / Swiss Army Knife custom card.
# Repository: https://github.com/AmoebeLabs/swiss-army-knife-card
#
# Author    : Mars @ AmoebeLabs.com
#
# License   : CC BY-SA, https://creativecommons.org/licenses/by/4.0/
#
# -----
# Description:
# SAK Example #12. Some wide cards and some animated circles!!!!!!!
#
# Refs:
#
################################################################################

title: SAKE12
path: sake12
panel: false
cards:
#-------------------------------------------------------------------------------
- type: vertical-stack
  cards:
    - type: horizontal-stack
      cards:
        - type: 'custom:swiss-army-knife-card'
          entities:
            - entity: sensor.u_s_air_quality_index
              name: 'Glabbeek'
            - entity: sensor.u_s_air_pollution_level
            - entity: sensor.u_s_air_quality_index
              secondary_info: last_changed
              format: relative

          # Define aspect ratio
          aspectratio: 6/1

          layout:
            styles:
              card:
              toolsets:

            toolsets:
              # ================================================================
              - toolset: line1
                position:
                  cx: 200
                  cy: 50
                tools:
                  # ------------------------------------------------------------
                  - type: line
                    position:
                      cx: 50
                      cy: 50
                      orientation: vertical
                      length: 50
                    styling:
                      line:
                        fill: var(--primary-text-color)
                        opacity: 0.5

              # ================================================================
              - toolset: line2
                position:
                  cx: 400
                  cy: 50
                tools:
                  # ------------------------------------------------------------
                  - type: line
                    position:
                      cx: 50
                      cy: 50
                      orientation: vertical
                      length: 50
                    styling:
                      line:
                        fill: var(--primary-text-color)
                        opacity: 0.5


              # ================================================================
              - toolset: colomn-icon
                position:
                  cx: 30
                  cy: 50
                tools:
                  # ------------------------------------------------------------
                  - type: icon
                    position:
                      cx: 50
                      cy: 50
                      align: center
                      icon_size: 30
                    entity_index: 0
                  - type: circle
                    position:
                      cx: 50
                      cy: 50
                      radius: 22
                    styles:
                      circle:
                        fill: none
                        stroke: var(--primary-text-color)
                        stroke-width: 3em
                        opacity: 1

              - toolset: colomn-name
                position:
                  cx: 120
                  cy: 50
                tools:
                  # ------------------------------------------------------------
                  - type: name
                    position:
                      cx: 50
                      cy: 50
                    entity_index: 0
                    styles:
                      name:
                        text-anchor: middle
                        font-size: 20em
                        font-weight: 700
                  # ------------------------------------------------------------
                  - type: state
                    position:
                      cx: 50
                      cy: 70
                    entity_index: 2
                    show:
                      uom: none
                    styles:
                      state:
                        text-anchor: middle
                        font-size: 10em
                        font-weight: 700

              - toolset: colomn-state
                position:
                  cx: 300
                  cy: 50
                tools:
                  # ------------------------------------------------------------
                  - type: icon
                    position:
                      cx: 25
                      cy: 25
                      align: end
                      icon_size: 30
                    entity_index: 1
                  # ------------------------------------------------------------
                  - type: state
                    position:
                      cx: 50
                      cy: 25
                    entity_index: 0
                    styles:
                      state:
                        text-anchor: start
                        font-size: 25em
                        font-weight: 700
                        fill: var(--primary-text-color)
                      uom:
                        fill: var(--primary-text-color)
                        font-weight: 700

                  # ------------------------------------------------------------
                  - type: 'segarc'
                    id: 0
                    position:
                      cx: 50
                      cy: 70
                      start_angle: 190
                      end_angle: 170
                      width: 8
                      radius_x: 405         # 20 degrees = 1/9 = 45*9 = 405
                      radius_y: 1
                    entity_index: 0
                    scale:
                      min: 0
                      max: 300
                      width: 6
                      offset: 12
                    show:
                      scale: true
                      style: 'colorstops'
                    segments:
                      colorstops:
                        gap: 0.1
                        colors:
                          0: '#A8E05F'
                          51: '#FDD74B'
                          101: '#FE9B57'
                          151: '#FE6A69'
                          201: '#A97ABC'
                          301: '#A87383'
                    styles:
                      foreground:
                        fill: darkgrey
                      background:
                        fill: var(--theme-sys-elevation-surface-neutral5)

              - toolset: colomn-history
                position:
                  cx: 500
                  cy: 50
                tools:
                  # ------------------------------------------------------------
                  - type: text
                    position:
                      orientation: vertical
                      cx: 50
                      cy: 20
                    text: "Last 24 hours"
                    styles:
                      text:
                        text-anchor: middle
                        font-size: 15em
                        font-weight: 700

                  # ------------------------------------------------------------
                  - type: bar
                    id: 1
                    entity_index: 0
                    position:
                      orientation: vertical
                      cx: 50
                      cy: 60
                      width: 150
                      height: 40
                      margin: 1
                    hours: 24
                    barhours: 1
                    show:
                      style: 'colorstops'
                    colorstops:
                      fill: true
                      colors:
                        0: '#A8E05F'
                        51: '#FDD74B'
                        101: '#FE9B57'
                        151: '#FE6A69'
                        201: '#A97ABC'
                        301: '#A87383'
                    styles:
                      bar:
                        stroke-linecap: square




    # ==========================================================================
    - type: horizontal-stack
      cards:
        #
        # Indoor Environment: Woonkamer
        #
        ########################################################################
        - type: 'custom:swiss-army-knife-card'
          entities:
            - entity: sensor.woonkamer
              name: 'Woonkamer'
              icon: mdi:sofa
              decimals: 1
            - entity: sensor.netatmo_kerkstraat_10_woonkamer_humidity
              decimals: 0
            - entity: sensor.netatmo_kerkstraat_10_woonkamer_co2
              decimals: 0
            - entity: sensor.netatmo_kerkstraat_10_woonkamer_noise
              decimals: 0
            - entity: sensor.bathroom_2f_iaq_linkquality
              decimals: 0
            - entity: sensor.woonkamer
              secondary_info: last_changed
              format: relative

          # Define aspect ratio
          aspectratio: 6/1

          layout:
            styles:
              card:
              toolsets:

            toolsets:
              # ================================================================
              - toolset: line1
                position:
                  cx: 200
                  cy: 50
                tools:
                  # ------------------------------------------------------------
                  - type: line
                    position:
                      cx: 50
                      cy: 50
                      orientation: vertical
                      length: 50
                    styling:
                      line:
                        fill: var(--primary-text-color)
                        opacity: 0.5

              # ================================================================
              - toolset: line2
                position:
                  cx: 500
                  cy: 50
                tools:
                  # ------------------------------------------------------------
                  - type: line
                    position:
                      cx: 50
                      cy: 50
                      orientation: vertical
                      length: 50
                    styling:
                      line:
                        fill: var(--primary-text-color)
                        opacity: 0.5

              # ================================================================
              - toolset: colomn-icon
                position:
                  cx: 30
                  cy: 50
                tools:
                  # ------------------------------------------------------------
                  - type: icon
                    position:
                      cx: 50
                      cy: 50
                      align: center
                      icon_size: 30
                    entity_index: 0
                  # ------------------------------------------------------------
                  - type: circle
                    position:
                      cx: 50
                      cy: 50
                      radius: 22
                    styles:
                      circle:
                        fill: none
                        stroke: var(--primary-text-color)
                        stroke-width: 3em
                        opacity: 1

              - toolset: colomn-name
                position:
                  cx: 120
                  cy: 50
                tools:
                  # ------------------------------------------------------------
                  - type: name
                    position:
                      cx: 50
                      cy: 50
                    entity_index: 0
                    styles:
                      name:
                        text-anchor: middle
                        font-size: 20em
                        font-weight: 700
                        opacity: 1

                  # ------------------------------------------------------------
                  - type: state
                    position:
                      cx: 50
                      cy: 70
                    entity_index: 5
                    show:
                      uom: none
                    styles:
                      state:
                        text-anchor: middle
                        font-size: 10em
                        font-weight: 700

              # ================================================================
              - toolset: colomn-temperature
                position:
                  cx: 260
                  cy: 50
                tools:
                  # ------------------------------------------------------------
                  - type: icon
                    icon: mdi:thermometer
                    position:
                      cx: 50
                      cy: 30
                      align: center
                      icon_size: 25
                    entity_index: 5

                  # ------------------------------------------------------------
                  - type: state
                    position:
                      cx: 50
                      cy: 55
                    entity_index: 0
                    show:
                      uom: bottom
                    styles:
                      state:
                        text-anchor: middle
                        font-size: 20em
                        font-weight: 700
                        fill: var(--primary-text-color)
                      uom:
                        fill: var(--primary-text-color)
                        font-weight: 700

                  # ------------------------------------------------------------
                  - type: 'segarc'
                    id: 0
                    position:
                      cx: 50
                      cy: 50
                      start_angle: 0
                      end_angle: 360
                      width: 6
                      radius: 40
                    entity_index: 0
                    scale:
                      min: 15
                      max: 25
                      width: 6
                      offset: 12
                    show:
                      scale: false
                      style: 'colorlist'
                    segments:
                      colorlist:
                        gap: 1
                        colors:
                          - var(--theme-sys-palette-primary50)
                    styles:
                      foreground:
                        fill: darkgrey
                      background:
                        fill: var(--theme-sys-elevation-surface-neutral4)
                        opacity: 1

              # ================================================================
              - toolset: colomn-humidity
                position:
                  cx: 355
                  cy: 50
                tools:
                  # ------------------------------------------------------------
                  - type: icon
                    position:
                      cx: 50
                      cy: 30
                      align: center
                      icon_size: 25
                    entity_index: 1

                  # ------------------------------------------------------------
                  - type: state
                    position:
                      cx: 50
                      cy: 55
                    entity_index: 1
                    show:
                      uom: bottom
                    styles:
                      state:
                        text-anchor: middle
                        font-size: 20em
                        font-weight: 800
                        fill: var(--primary-text-color)
                      uom:
                        fill: var(--primary-text-color)
                        font-weight: 800

                  # ------------------------------------------------------------
                  - type: 'segarc'
                    id: 0
                    position:
                      cx: 50
                      cy: 50
                      start_angle: 0
                      end_angle: 360
                      width: 6
                      radius: 40
                    entity_index: 1
                    scale:
                      min: 0
                      max: 100
                      width: 4
                      offset: 12
                    show:
                      scale: false
                      style: 'colorlist'
                    segments:
                      colorlist:
                        gap: 1
                        colors:
                          - var(--theme-sys-palette-primary45)
                    styles:
                      foreground:
                        fill: darkgrey
                      background:
                        fill: var(--theme-sys-elevation-surface-neutral4)
                        opacity: 1

              # ================================================================
              - toolset: colomn-co2
                position:
                  cx: 450
                  cy: 50
                tools:
                  # ------------------------------------------------------------
                  - type: icon
                    icon: mdi:molecule-co2
                    position:
                      cx: 50
                      cy: 30
                      align: center
                      icon_size: 25
                    entity_index: 2

                  # ------------------------------------------------------------
                  - type: state
                    position:
                      cx: 50
                      cy: 55
                    entity_index: 2
                    show:
                      uom: bottom
                    styles:
                      state:
                        text-anchor: middle
                        font-size: 20em
                        font-weight: 700
                        fill: var(--primary-text-color)
                      uom:
                        fill: var(--primary-text-color)
                        font-weight: 700

                  # ------------------------------------------------------------
                  - type: 'segarc'
                    id: 0
                    position:
                      cx: 50
                      cy: 50
                      start_angle: 0
                      end_angle: 360
                      width: 6
                      radius: 40
                    entity_index: 2
                    scale:
                      min: 300
                      max: 2500
                      width: 6
                      offset: 12
                    show:
                      scale: false
                      style: 'colorlist'
                    segments:
                      colorlist:
                        gap: 1
                        colors:
                          - var(--theme-sys-palette-primary40)
                    styles:
                      foreground:
                        fill: darkgrey
                      background:
                        fill: var(--theme-sys-elevation-surface-neutral4)
                        opacity: 1

              # ================================================================
              - toolset: colomn-noise
                position:
                  cx: 540
                  cy: 50
                tools:
                  # ------------------------------------------------------------
                  - type: icon
                    icon: mdi:ear-hearing
                    position:
                      cx: 30
                      cy: 30
                      align: right
                      icon_size: 25
                    entity_index: 3

                  # ------------------------------------------------------------
                  - type: state
                    position:
                      cx: 70
                      cy: 30
                    entity_index: 3
                    show:
                      uom: none
                    styles:
                      state:
                        text-anchor: middle
                        font-size: 18em
                        font-weight: 700
                        fill: var(--primary-text-color)
                      uom:
                        fill: var(--primary-text-color)
                        font-weight: 700

                  # ------------------------------------------------------------
                  - type: 'segarc'
                    id: 0
                    position:
                      cx: 70
                      cy: 30
                      start_angle: 0
                      end_angle: 360
                      width: 3
                      radius: 18
                    entity_index: 3
                    scale:
                      min: 0
                      max: 100
                      width: 6
                      offset: 12
                    show:
                      scale: false
                      style: 'colorlist'
                    segments:
                      colorlist:
                        gap: 1
                        colors:
                          - var(--theme-sys-palette-tertiary45)
                    styles:
                      foreground:
                        fill: darkgrey
                      background:
                        fill: var(--theme-sys-elevation-surface-neutral4)
                        opacity: 1

              # ================================================================
              - toolset: colomn-linkquality
                position:
                  cx: 540
                  cy: 50
                tools:
                  # ------------------------------------------------------------
                  - type: icon
                    position:
                      cx: 30
                      cy: 70
                      align: right
                      icon_size: 25
                    entity_index: 4

                  # ------------------------------------------------------------
                  - type: state
                    position:
                      cx: 70
                      cy: 70
                    entity_index: 4
                    show:
                      uom: none
                    styles:
                      state:
                        text-anchor: middle
                        font-size: 18em
                        font-weight: 700
                        fill: var(--primary-text-color)
                      uom:
                        fill: var(--primary-text-color)
                        font-weight: 700

                  # ------------------------------------------------------------
                  - type: 'segarc'
                    id: 0
                    position:
                      cx: 70
                      cy: 70
                      start_angle: 0
                      end_angle: 360
                      width: 3
                      radius: 18
                    entity_index: 4
                    scale:
                      min: 0
                      max: 100
                      width: 6
                      offset: 12
                    show:
                      scale: false
                      style: 'colorlist'
                    segments:
                      colorlist:
                        gap: 1
                        colors:
                          - var(--theme-sys-palette-tertiary45)
                    styles:
                      foreground:
                        fill: darkgrey
                      background:
                        fill: var(--theme-sys-elevation-surface-neutral4)
                        opacity: 1

Problem solved!

Problem solved!
Problem was a typo in 1 entity name. :wink:

I’m looking at this, and it looks good…
But I struggle to figure out how to get started.
Ideally I’d want to build my own dashboard with elements from SAK.
But all guides seem to need to use the templates that you get in the .zip file.
Is this correct?

What the “aaaaaaaaaaaaaaah” realisation I’m missing?

Hi,

Small question.
At this moment I use Mushroom entity button cards to call trigger/services for my HVAC environment, see screenshot below!
My question, is this also possible with SAK?
If yes, has anyone a example? :slight_smile:

Yes, this should be possible and I’m playing with a similar scenario currently with a ceiling fan controller and setting different speeds.

The approach I’m taking is to have a ‘button’ for each mode (low, medium, high) and have the user action for each button set the corresponding mode. (Probably going to use a rounded rectangle for the buttons. For styling, I’m going to set the style based on the mode attribute, if the fan is on low the ‘low’ button with change, and so on. My desire is to have all of this, including the light control as well, on a single card.

I just have my idea on paper for now so not super easy to share. When I get it working I plan on sharing the config. If you reach a functional state with yours first, please share!

Ok thanks James, I will do! :+1:

Here is what I was able to accomplish:

image

The fan icon button calls the fan.toggle service and the three buttons on the right side call the fan.set_preset_mode service providing their respective mode.

Here is the code for this card
      # Cealing fan/light card
      - type: custom:swiss-army-knife-card
        aspectratio: 5/1
        disable_card: false
        entities:
          - entity: light.sonoff_1001589996_1
            name: "Ceiling Fan Light"
            icon: mdi:ceiling-fan-light

          - entity: fan.sonoff_1001589996
            name: "Ceiling Fan"
            icon: mdi:fan
            
          - entity: fan.sonoff_1001589996
            name: "Preset Mode"
            icon: mdi:fan
            attribute: preset_mode
        layout:
          toolsets:
            - toolset: half-circle
              position:
                cx: 0
                cy: 50
              tools:
                - type: circle
                  position:
                    cx: 50
                    cy: 50
                    radius: 48
                  styles:
                    circle:
                      fill: none
                      stroke: var(--theme-sys-color-secondary)
                      stroke-width: 3em
                - type: icon
                  position:
                    cx: 72
                    cy: 50
                    align: center
                    icon_size: 40
                  icon: mdi:ceiling-fan
                  styles:
                    icon:
                      fill: var(--theme-sys-color-secondary)
                      opacity: 0.9
            - toolset: card-label
              position:
                cx: 125
                cy: 50
              tools:
                - type: text
                  position:
                    cx: 0
                    cy: 50
                  text: "Ceiling Fan"
                  styles:
                    text:
                      text-anchor: start
                      font-size: 20em
                      font-weight: 700
                      opacity: 1
                      overflow: hidden
            - toolset: vertical-line-1
              position:
                cx: 200
                cy: 50
              tools:
                - type: line
                  position:
                    cx: 50
                    cy: 50
                    orientation: vertical
                    length: 75
                  styles:
                    line:
                      fill: var(--theme-sys-color-secondary)
                      opacity: 0.7
            - toolset: light-state-button
              position:
                cx: 250
                cy: 50
              tools:
                - type: circle
                  position:
                    cx: 50
                    cy: 50
                    radius: 35
                  entity_index: 0
                  animations:
                    - state: "on"
                      styles:
                        circle:
                          stroke: orange
                          opacity: 1
                          filter: url(#is-1)
                    - state: "off"
                      styles:
                        circle:
                          stroke: var(--theme-sys-color-secondary)
                          opacity: 1
                  styles:
                    circle:
                      fill: none
                      stroke-width: 4em
                      transition: 'all 0.8s ease'
                - type: icon
                  position:
                    cx: 50
                    cy: 50
                    align: center
                    icon_size: 50
                  entity_index: 0
                  animations:
                    - state: "on"
                      styles:
                        icon:
                          color: orange
                          fill: orange
                          opacity: 1
                    - state: "off"
                      styles:
                        icon:
                          color: var(--theme-sys-color-secondary)
                          fill: var(--theme-sys-color-secondary)
                          opacity: 1
                  styles:
                    icon:
                      transition: 'all 0.8s ease'
                - type: circle # transparent shape that covers the whole button to act as the link
                  position:
                    cx: 50
                    cy: 50
                    radius: 35
                  entity_index: 0
                  styles:
                    circle:
                      fill: rgba(0,0,0,0)
                      stroke: none
                  user_actions:
                    tap_action:
                      haptic: success
                      actions:
                        - action: call-service
                          service: light.toggle
            - toolset: fan-state-button
              position:
                cx: 350
                cy: 50
              tools:
                - type: circle
                  position:
                    cx: 50
                    cy: 50
                    radius: 35
                  entity_index: 1
                  animations:
                    - state: "on"
                      styles:
                        circle:
                          stroke: orange
                          opacity: 1
                          filter: url(#is-1)
                    - state: "off"
                      styles:
                        circle:
                          stroke: var(--theme-sys-color-secondary)
                          opacity: 1
                  styles:
                    circle:
                      fill: none
                      stroke-width: 4em
                      transition: 'all 0.8s ease'
                - type: icon
                  position:
                    cx: 50
                    cy: 50
                    align: center
                    icon_size: 50
                  entity_index: 1
                  animations:
                    - state: "on"
                      styles:
                        icon:
                          color: orange
                          fill: orange
                          opacity: 1
                    - state: "off"
                      styles:
                        icon:
                          color: var(--theme-sys-color-secondary)
                          fill: var(--theme-sys-color-secondary)
                          opacity: 1
                  styles:
                    icon:
                      transition: 'all 0.8s ease'
                - type: circle # transparent shape that covers the whole button to act as the link
                  position:
                    cx: 50
                    cy: 50
                    radius: 35
                  entity_index: 1
                  styles:
                    circle:
                      fill: rgba(0,0,0,0)
                      stroke: none
                  user_actions:
                    tap_action:
                      haptic: success
                      actions:
                        - action: call-service
                          service: fan.toggle
            - toolset: preset-mode-buttons
              position:
                cx: 450
                cy: 50
              tools:
                # Preset Mode: Low
                - type: rectangle
                  position:
                    cx: 50
                    cy: 25
                    height: 20
                    width: 70
                    rx: 10
                  entity_index: 2
                  animations:
                    - state: "low"
                      styles:
                        rectangle:
                          stroke: orange
                          opacity: 1
                    - state: "medium"
                      styles:
                        rectangle:
                          stroke: var(--theme-sys-color-secondary)
                          opacity: 1
                    - state: "high"
                      styles:
                        rectangle:
                          stroke: var(--theme-sys-color-secondary)
                          opacity: 1
                    - state: "off"  # this state value is never recorded.
                      styles:
                        rectangle:
                          stroke: var(--theme-sys-color-secondary)
                          opacity: 1
                  styles:
                    rectangle:
                      fill: none
                      stroke-width: 2em
                      transition: 'all 0.8s ease'
                - type: text
                  position:
                    cx: 50
                    cy: 25
                  text: "Low"
                  styles:
                    text:
                      text-anchor: middle
                      font-size: 12em
                      font-weight: 700
                      opacity: 1
                - type: rectangle # transparent shape that covers the whole button to act as the link
                  position:
                    cx: 50
                    cy: 25
                    height: 20
                    width: 70
                    rx: 10
                  entity_index: 2
                  styles:
                    rectangle:
                      fill: rgba(0,0,0,0)
                      stroke: none
                  user_actions:
                    tap_action:
                      haptic: success
                      actions:
                        - action: call-service
                          service: fan.set_preset_mode
                          service_data:
                            preset_mode: "low"
                # Preset Mode: Medium
                - type: rectangle
                  position:
                    cx: 50
                    cy: 50
                    height: 20
                    width: 70
                    rx: 10
                  entity_index: 2
                  animations:
                    - state: "low"
                      styles:
                        rectangle:
                          stroke: var(--theme-sys-color-secondary)
                          opacity: 1
                    - state: "medium"
                      styles:
                        rectangle:
                          stroke: orange
                          opacity: 1
                    - state: "high"
                      styles:
                        rectangle:
                          stroke: var(--theme-sys-color-secondary)
                          opacity: 1
                    - state: "off"
                      styles:
                        rectangle:
                          stroke: var(--theme-sys-color-secondary)
                          opacity: 1
                  styles:
                    rectangle:
                      fill: none
                      stroke-width: 2em
                      transition: 'all 0.8s ease'
                - type: text
                  position:
                    cx: 50
                    cy: 50
                  text: "Medium"
                  styles:
                    text:
                      text-anchor: middle
                      font-size: 12em
                      font-weight: 700
                      opacity: 1
                - type: rectangle # transparent shape that covers the whole button to act as the link
                  position:
                    cx: 50
                    cy: 50
                    height: 20
                    width: 70
                    rx: 10
                  entity_index: 2
                  styles:
                    rectangle:
                      fill: rgba(0,0,0,0)
                      stroke: none
                  user_actions:
                    tap_action:
                      haptic: success
                      actions:
                        - action: call-service
                          service: fan.set_preset_mode
                          service_data:
                            preset_mode: "medium"
                # Preset Mode: High
                - type: rectangle
                  position:
                    cx: 50
                    cy: 75
                    height: 20
                    width: 70
                    rx: 10
                  entity_index: 2
                  animations:
                    - state: "low"
                      styles:
                        rectangle:
                          stroke: var(--theme-sys-color-secondary)
                          opacity: 1
                    - state: "medium"
                      styles:
                        rectangle:
                          stroke: var(--theme-sys-color-secondary)
                          opacity: 1
                    - state: "high"
                      styles:
                        rectangle:
                          stroke: orange
                          opacity: 1
                    - state: "off"
                      styles:
                        rectangle:
                          stroke: var(--theme-sys-color-secondary)
                          opacity: 1
                  styles:
                    rectangle:
                      fill: none
                      stroke-width: 2em
                      transition: 'all 0.8s ease'
                - type: text
                  position:
                    cx: 50
                    cy: 75
                  text: "High"
                  styles:
                    text:
                      text-anchor: middle
                      font-size: 12em
                      font-weight: 700
                      opacity: 1
                - type: rectangle # transparent shape that covers the whole button to act as the link
                  position:
                    cx: 50
                    cy: 75
                    height: 20
                    width: 70
                    rx: 10
                  entity_index: 2
                  styles:
                    rectangle:
                      fill: rgba(0,0,0,0)
                      stroke: none
                  user_actions:
                    tap_action:
                      haptic: success
                      actions:
                        - action: call-service
                          service: fan.set_preset_mode
                          service_data:
                            preset_mode: "high"

There is still one issue outstanding on this setup. When the fan is turned off the preset_mode: is set to null according to the details in the state developer tools. I have not yet figured out how to capture that value in the automation section of the tools. I tried checking for the following state values:

- state: "null"

- state: null

- state: "none"

- state: none

- state: "" # Double quotes, no space

- state: " " # Double quotes with a space

- state: '' # Single quote, no space

- state: ' ' # Single quote with a space

- state:     # just a blank element

None of these captured the null state of the preset_mode when the fan entity is turned off. The result of this is that when the fan is turned off the last preset mode remains active. If the page is refreshed the style of the buttons reverts to a black stroke color. When the fan is turned on again the styles for each button are re-established.

If anyone has any suggestions on how to handle this null state, please share!

@AmoebeLabs any suggestions? Would there be a way to set a default if none of the - state values match?

Happy Automating!

UPDATE: State issue solved

                  animations:
                    - state: 'low'
                      styles:
                        rectangle:
                          stroke: orange
                          opacity: 1
                    - state: 'low'
                      operator: '!=' # <-- This was the key to the solution.  Sometimes it helps to re-read the docs (and read the whole document)!
                      styles:
                        rectangle:
                          stroke: var(--theme-sys-color-secondary)
                          opacity: 1

@Symbiot78 I just posted the code for a card I created that does not use any templates. It does, however, rely on the CSS and SVG includes that are discussed in the install docs.

If you downloaded the examples, view-sake1.yml is all raw cards as well, no templates.

If you are not going to install the examples in your HASS instance and do not intend to use templates for cards or other components, all you should need are the files that are located in the www/community/swiss-army-knife-card directory after your install from HACS.

I will say that because this is a 100% custom card and you must define every object used on the cards, not using templates will cause your dashboard views to grow significantly. I understand wanting to start simple to learn but I strongly encourage you to explore the use of decluttering_templates for full cards and/or sak_templates for the individual components in a card.

The code below is an example dashboard of how you can use SAK without calling the decluttering card or sak_templates. It uses the sun entity which every default install of HASS has. It uses no templates but does use the spin animation to test that the base sak_includes are working.

Test Dashboard
title: "Swiss Army Knife Card Testing"
views:
  - title: "Test"
    type: masonry
    icon: mdi:home-assistant
    path: sak-test
    cards:
      # Create a vertical layout of cards
      - type: vertical-stack
        cards:
          # The first SAK card
          - type: custom:swiss-army-knife-card
            aspectratio: 1/1
            disable_card: false
            entities:
              # Sun entity that is built in to every default deployment of HASS
              - entity: sun.sun
                name: "Where is the Sun?"
                icon: mdi:sun-compass
            # Begin the graphical configuration of the SAK card
            layout:
              toolsets:
                - toolset: hello-world
                  position: # center the toolset in the 1/1 card
                    cx: 50
                    cy: 50
                  tools:
                    - type: text
                      position: # place the text in the upper-left corner of the toolset
                        cx: 5
                        cy: 10
                      text: "Hello World!"
                      styles:
                        text:
                          text-anchor: start
                          font-size: 12em
                          font-weight: 700
                    - type: name
                      position:
                        cx: 50
                        cy: 25
                      entity_index: 0
                      styles:
                        name:
                          text-anchor: middle
                          font-size: 10em
                          font-weight: bolder
                    - type: icon
                      position: # place the icon in the center of the toolset
                        cx: 50
                        cy: 50
                        align: center
                        icon_size: 35
                      entity_index: 0
                      styles:
                        icon:
                          color: orange
                          animation: spin 5s infinite linear
                    - type: state
                      position:
                        cx: 50
                        cy: 80
                      entity_index: 0
                      show:
                        uom: none
                      styles:
                        state:
                          text-anchor: middle
                          font-size: 12em
                          font-weight: bolder

Hi James,

Great work! I have used your config to built my custom HVAC dashboard, and it works! :slight_smile:
But maybe one additional question, do you know why some of us needs to reload the sak config and refresh HA each time to keep the sak cards working?
I’m running in a hybrid mode.

regards,

 Jurgen

@dvbit What did you do to fix it? I have the same problem that the slider doesn’t work…