There are a lot of different options and themes that you could use to create a Dashboard in Home Assistant. Probably I will change and test different options in future but currently I’ve based my solution on two custom components made by the user thomasloven:
Layout-card custom component improves Lovelace layout control and gives the ability to setup a 3 columns layout.
Card-mod custom component gives the ability to apply CSS styles to almost any Lovelace element so I can control size, color, font…
The final result I would obtain is the following:

Custom components installation
Easiest way to install the two custom components is from HACS – Frontend, search the two component and install them:

Create your own Floor plan
Floor plan is the central part of my dashboard, and it is interactive so that I can switch on/off lights clicking on the plan position of each light.
I’ve used this web tool to create my floor plan: https://floorplanner.com
I’ve choose this one because it’s free, with some limitations, and mostly because includes many nice furniture 3D models.

Once completed the design it’s possible to export the plan in 3D or 2D view to a png file, choosing also lightning settings, to simulate Day light change from morning to night. In my case I have used 3 different lightning conditions: day, mid and night.
Using WinSCP (link) application I’ve finally uploaded the pictures to my Home Assistant under the WWW folder and images/3dfloorplan sub folders that I’ve created for this specific purpose.

Create the Dashboard
Create a new Dashboard from the Configuration menu

Type the Title, select and Icon and click CREATE

Click on the top-right corner 3 dots menu, a click Edit Dashboard

Enter Raw configuration editor mode and replace existing code with the following one.

This is my one code, with my own entities, so you have to replace them with your entities (swicthes, lights and so on)
I can suggest this very useful resource for card-mod styles: Card-mod – Add css styles to any lovelace card
title: Casa
views:
- theme: Backend-selected
background: >-
center / cover no-repeat url('/local/images/custom_ui/background_1.png')
fixed
background-position: cover;
background-repeat: no-repeat;
background-size: 100% 114%;
path: wallpanel
icon: mdi:tablet-dashboard
type: panel
badges: []
cards:
- type: custom:layout-card
layout_type: grid
layout:
grid-template-columns: 30% 50% 20%
grid-template-rows: 100% 100% 100%
cards:
- type: vertical-stack
cards:
- type: entities
entities:
- entity: light.switch_3
- entity: light.switch_6
- entity: light.switch_4
- entity: light.switch_7
- entity: light.switch_5
- entity: switch.piantana
icon: mdi:floor-lamp-outline
name: Piantana
- entity: cover.rolling_shutter_switch_1_2
- entity: cover.rolling_shutter_switch_2_2
title: Zona Giorno
card_mod:
style: |
ha-card {
border-radius: 20px;
margin: 0px;
padding: 0px;
padding-bottom: 6px;
-webkit-box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
-moz-box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
font-size:12px;
--switch-checked-color: yellow;
--switch-checked-button-color: yellow;
--switch-checked-track-color: yellow;
line-height:20px;
--mdc-icon-size:20px;
background: url('/local/images/custom_ui/background_1.png')
}
.card-header {
padding-top: 12px;
padding-left: 18px;
padding-bottom: 10px;
font-size:18px;
font-weight:bold;
line-height:32px;
height:32px;
}
hui-generic-entity-row$: |
state-badge {
height:24px;
}
div {
padding-left:4px;
height:24px;
}
- type: entities
card_mod:
style: |
ha-card {
border-radius: 20px;
margin: 0px;
margin-top: 8px;
padding: 0px;
padding-bottom: 6px;
-webkit-box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
-moz-box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
font-size:12px;
--switch-checked-color: yellow;
--switch-checked-button-color: yellow;
--switch-checked-track-color: yellow;
line-height:20px;
--mdc-icon-size:20px;
background: url('/local/images/custom_ui/background_1.png')
}
.card-header {
padding-top: 12px;
padding-left: 18px;
padding-bottom: 10px;
font-size:18px;
font-weight:bold;
line-height:32px;
height:32px;
}
hui-generic-entity-row$: |
state-badge {
height:24px;
}
div {
padding-left:4px;
height:24px;
}
entities:
- entity: light.switch_9
- entity: light.switch_2
- entity: light.switch_8
- entity: light.switch_1
title: Zona Notte
- type: custom:layout-break
- type: picture-elements
elements:
- entity: sensor.brightness_sun
image: /local/images/3DFloorplan/floorplan_day.png?v=2
state_image:
bright: /local/images/3DFloorplan/floorplan_day.png?v=2
mid: /local/images/3DFloorplan/floorplan_mid.png?v=2
dark: /local/images/3DFloorplan/floorplan_dark.png?v=2
black: /local/images/3DFloorplan/floorplan_dark.png?v=2
style:
left: 50%
top: 50%
width: 100%
tap_action:
action: none
type: image
- entity: light.switch_1
type: state-icon
title: Luce Bagno
icon: mdi:lightbulb
style:
top: 83%
left: 41%
'--paper-item-icon-color': '#000000'
width: 40px
height: 40px
line-height: 38px
border-radius: 50%
transform: scale(1.0,1.0)
text-align: center
background-color: rgba(255, 255, 255, 0.3)
tap_action:
action: toggle
- entity: light.switch_2
type: state-icon
title: Luce Studio
icon: mdi:lightbulb
style:
top: 70%
left: 16%
'--paper-item-icon-color': '#000000'
width: 40px
height: 40px
line-height: 38px
border-radius: 50%
transform: scale(1.0,1.0)
text-align: center
background-color: rgba(255, 255, 255, 0.3)
tap_action:
action: toggle
- entity: light.switch_3
type: state-icon
title: Luce Sala
icon: mdi:lightbulb
style:
top: 26%
left: 65%
'--paper-item-icon-color': '#000000'
width: 40px
height: 40px
line-height: 38px
border-radius: 50%
transform: scale(1.0,1.0)
text-align: center
background-color: rgba(255, 255, 255, 0.3)
tap_action:
action: toggle
- entity: light.switch_4
type: state-icon
title: Luce Cucina
icon: mdi:lightbulb
style:
top: 53%
left: 60%
'--paper-item-icon-color': '#000000'
width: 40px
height: 40px
line-height: 38px
border-radius: 50%
transform: scale(1.0,1.0)
text-align: center
background-color: rgba(255, 255, 255, 0.3)
tap_action:
action: toggle
- entity: light.switch_5
type: state-icon
title: Luce Sgabuzzino
icon: mdi:lightbulb
style:
top: 43%
left: 14%
'--paper-item-icon-color': '#000000'
width: 40px
height: 40px
line-height: 38px
border-radius: 50%
transform: scale(1.0,1.0)
text-align: center
background-color: rgba(255, 255, 255, 0.3)
tap_action:
action: toggle
- entity: light.switch_6
type: state-icon
title: Luce Ingresso
icon: mdi:lightbulb
style:
top: 30%
left: 34%
'--paper-item-icon-color': '#000000'
width: 40px
height: 40px
line-height: 38px
border-radius: 50%
transform: scale(1.0,1.0)
text-align: center
background-color: rgba(255, 255, 255, 0.3)
tap_action:
action: toggle
- entity: light.switch_7
type: state-icon
title: Luce Isola
icon: mdi:lightbulb
style:
top: 45%
left: 54%
'--paper-item-icon-color': '#000000'
width: 40px
height: 40px
line-height: 38px
border-radius: 50%
transform: scale(1.0,1.0)
text-align: center
background-color: rgba(255, 255, 255, 0.3)
tap_action:
action: toggle
- entity: light.switch_8
type: state-icon
title: Luce Corridoio
icon: mdi:lightbulb
style:
top: 58%
left: 37%
'--paper-item-icon-color': '#000000'
width: 40px
height: 40px
line-height: 38px
border-radius: 50%
transform: scale(1.0,1.0)
text-align: center
background-color: rgba(255, 255, 255, 0.3)
tap_action:
action: toggle
- entity: light.switch_9
type: state-icon
title: Luce Camera
icon: mdi:lightbulb
style:
top: 78%
left: 70%
'--paper-item-icon-color': '#000000'
width: 40px
height: 40px
line-height: 38px
border-radius: 50%
transform: scale(1.0,1.0)
text-align: center
background-color: rgba(255, 255, 255, 0.3)
tap_action:
action: toggle
- entity: cover.rolling_shutter_switch_1_2
type: state-icon
title: Tapparella Sala
style:
top: 25%
left: 90%
'--paper-item-icon-color': '#000000'
width: 40px
height: 40px
line-height: 38px
border-radius: 50%
transform: scale(1.0,1.0)
text-align: center
background-color: rgba(0, 0, 0, 0.3)
tap_action:
action: toggle
- entity: cover.rolling_shutter_switch_2_2
type: state-icon
title: Tapparella Cucina
style:
top: 54%
left: 90%
'--paper-item-icon-color': '#000000'
width: 40px
height: 40px
line-height: 38px
border-radius: 50%
transform: scale(1.0,1.0)
text-align: center
background-color: rgba(0, 0, 0, 0.3)
tap_action:
action: toggle
- entity: sensor.kpad_battery_level
type: state-badge
title: null
style:
top: 6%
left: 74%
font-size: 10px
color: black
'--label-badge-text-color': magenta
'--label-badge-red': green
'--label-badge-background-color': white
- entity: sensor.sensore_temperatura_terrazzo_temperature
type: state-badge
title: null
style:
top: 6%
left: 94%
font-size: 10px
color: black
'--label-badge-text-color': magenta
'--label-badge-red': green
'--label-badge-background-color': white
- entity: sensor.0x00158d00045bd50d_temperature
type: state-badge
title: null
style:
top: 6%
left: 84%
font-size: 10px
color: black
'--label-badge-text-color': magenta
'--label-badge-red': green
'--label-badge-background-color': white
image: /local/images/3DFloorplan/floorplan_day.png?v=4
card_mod:
style: |
ha-card {
border-radius: 10px;
-webkit-box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
-moz-box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
--ha-card-background: white
}
- type: custom:layout-break
- type: vertical-stack
cards:
- type: grid
cards:
- type: gauge
min: 0
max: 100
entity: sensor.0x00158d00045bd50d_temperature
needle: true
card_mod:
style: |
ha-card {
border-radius: 10px;
-webkit-box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
-moz-box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
background: url('/local/images/custom_ui/background_1.png')
}
div.name {
font-size:12px;
}
name: Sala
- type: gauge
min: 0
max: 100
entity: sensor.sensore_temperatura_terrazzo_temperature
needle: true
card_mod:
style: |
ha-card {
border-radius: 10px;
-webkit-box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
-moz-box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
background: url('/local/images/custom_ui/background_1.png')
}
div.name {
font-size:12px;
}
name: Terrazzo
- type: gauge
min: 0
name: Consumo
unit: Kw
entity: sensor.f20t60a_kw
needle: true
severity:
green: 0
yellow: 2.5
red: 3
max: 3.3
card_mod:
style: |
ha-card {
border-radius: 10px;
-webkit-box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
-moz-box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
background: url('/local/images/custom_ui/background_1.png')
}
span {
font-size:12px;
}
- type: button
tap_action:
action: call-service
service: scene.turn_on
service_data: {}
target:
entity_id: scene.luci_spente
entity: scene.luci_spente
show_state: false
card_mod:
style: |
ha-card {
border-radius: 10px;
-webkit-box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
-moz-box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
background: url('/local/images/custom_ui/background_1.png')
}
span {
font-size:12px;
}
- type: button
tap_action:
action: call-service
service: scene.turn_on
service_data: {}
target:
entity_id: scene.tapparelle_basse
entity: scene.tapparelle_basse
show_state: false
card_mod:
style: |
ha-card {
border-radius: 10px;
-webkit-box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
-moz-box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
background: url('/local/images/custom_ui/background_1.png')
}
span {
font-size:12px;
}
- type: button
tap_action:
action: call-service
service: script.tapparelle_aperte
service_data: {}
target: {}
entity: script.tapparelle_aperte
show_state: false
card_mod:
style: |
ha-card {
border-radius: 10px;
-webkit-box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
-moz-box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
background: url('/local/images/custom_ui/background_1.png')
}
span {
font-size:12px;
}
- type: button
tap_action:
action: call-service
service: script.box_bidoni
service_data: {}
target: {}
entity: script.box_bidoni
show_state: true
card_mod:
style: |
ha-card {
border-radius: 10px;
-webkit-box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
-moz-box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
background: url('/local/images/custom_ui/background_1.png')
}
span {
font-size:12px;
}
- type: button
tap_action:
action: toggle
entity: switch.pompa_acqua
show_state: true
card_mod:
style: |
ha-card {
border-radius: 10px;
-webkit-box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
-moz-box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
background: url('/local/images/custom_ui/background_1.png')
}
span {
font-size:12px;
}
- type: button
tap_action:
action: toggle
entity: switch.citofono_apri_porta
icon: mdi:door-open
name: Portone
card_mod:
style: |
ha-card {
border-radius: 10px;
-webkit-box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
-moz-box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
background: url('/local/images/custom_ui/background_1.png')
}
span {
font-size:12px;
}
- type: button
tap_action:
action: toggle
entity: vacuum.sterminatore
name: Vacuum
card_mod:
style: |
ha-card {
border-radius: 10px;
-webkit-box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
-moz-box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
box-shadow: 0px 3px 6px 3px rgba(0,0,0,0.48);
background: url('/local/images/custom_ui/background_1.png')
}
span {
font-size:12px;
}
square: true
columns: 2
Having read this I thought it was really informative.
I appreciate you finding the time and energy to put this informative article
together. I once again find myself personally spending a significant amount
of time both reading and commenting. But so what, it was still worth
it!
my website: minecraft coloring sheets
Great post! Exactly what I was looking for. You mentioned that we need to change our entities, which makes sense. But do we need to change anything else like the icon positions? I’m new to code but I figure there is something in there that defines where the icons are located, correct?
Hi, and thank you!
Yes each Entity’s Icon that is over the floorplan must be positioned according to your own room and light position. Each entity has a section “style” with “top” and “left” attributes that you have to adjust to place it exactly where you want.