Floorplan for Home Assistant

It’s possible, but it’s the same one that works in the original Floorplan and the previous version of this card

Find finds it, which doesn’t surprise me, but I can try removing and adding a fresh one, and worst case rebuild the whole thing :grimacing:

Thanks

Welll, bleep me, that worked…

WTF

At least now I “only” have to go and re-create a few dozens of carefully placed shapes :joy:

Thanks

1 Like

I tried all that but it still stays cut off. I don’t know if something else is interfering with this but I don’t have any modifications on that particular view. It’s these from HACS:

battery-state-card.js
floorplan.js
card-mod.js
fold-entity-row.js
hui-element.js
layout-card.js
multiple-entity-row.js
mini-graph-card-bundle.js
stack-in-card.js
text-divider-row.js
banner-card.js?v=1
button-card.js
button-text-card.js
card-tools.js
custom-header.js
swipe-card.js

Thanks for the advice on making it bigger, I’ll definitely do that when this works haha.

So it works fine without the vertical stack? I just tried adding an entity and it is working fine for me with or without the vertical stack. There is something unusual about your SVG I thnk because of how it gets clipped if full_height: true isn’t added.

Unfortunately I have to sign off for two days as I am going away so hopefully someone else might chime in.

The only other thing to perhaps do just to get it working is I assume this is the background of your floorplan and you will put all the inteactivity on top? If so you can just screen capture the image and save as PNG or export it to PNG from within Inkscape. Then create a new SVG in inkscape and import the PNG as the background image and then go from there. This is how I started my floorplan because I created it in SweetHome3D first. I now just have a bunch of icons and other elements layered on top of it.

Someone else more knowledgable about SVGs might pop in with some better assistance if that won’t work for you. Good luck!

It doesn’t work now with or without the vertical stack. Still clipped on the side. I’ll try to redo the svg file with your instructions, we will see if that helps

Edit: It helped, now I can see the whole plan. Procedure was: Export to PNG > Import back in inkscape > save as SVG.

Now onto making it big

Help please, is it posible to make svg zoom in/out in mobile app (with two fingers)?
In first floorplan version was a key, but it’s missing in ha-floorplan ??

If you want to support panning and zooming within your SVG file, add the following:

      pan_zoom:

https://github.com/bumbu/svg-pan-zoom ??

Look in the app settings. It is in GENERAL in the IOS app

Hi, you speak about zoom? I use an Android app and haven’t this feature…

A quick Google search suggests it doesn’t work on the Android app.You will need to open a discussion in that forum Home Assistant Companion for Android - Home Assistant Community

1 Like

Hi guys, this would be my first posting here :wink:
So i’ve spent many hours getting my floorplan up and running and by now I’ve got one floor of my house pretty much operational. I went over to my phone in the companion app to look at it and in the companion i’m getting an error:
WARNING CONFIG Cannot find element ‘sensor.some-element’ in SVG file
It’s stating that it can’t find a total of 5 elements (a washing machine, a binary sensor from my PC, a group for my window covers, the climate Dyson fan and a media player) out of a total of about 10 (some lights, switches and sensors including that Dyson fan) elements i have implemented by now.
The weird thing is, my HA in chrome can find all of those elements and provide information or toggle them and so on.
What am I doing wrong here?

Could be a caching issue. Do you have the cache: false option

  image:
    location: /local/floorplan/examples/home/home.svg
    cache: true

Nope, I didn’t have that option so added it to the yaml code, restarten HA and the companion but had the same result, the same “elements” are somehow still not available in the companion. I also decided to open HA from the mobile device’s browser, in there the entities DO show up…
Looks like an issue with HA floorplan and companion?

Are you using a different SVG for mobile devices?

Ok, so somehow i sort of solved it. Mind you I’m stating a SORT OF…

After adding a new integration to HA i wound up adding NGINX (combination of companion app, smartthings and google nest did not work properly without it).
Now that I’ve got NGINX operational i see ALL of the elements/entities in HA-floorplan in the companion app

Yeah OK it doesn’t appear this is a HA problem then… For what its worth I use the IOS ap and Android app and they both work fine for me…

Ok, so here’s another few questions.
Before i ask them, here’s my setup, for now it’s just the 3rd floor:


And one with lights rurned off and the music on (and the PC on):

And the YAML code that goes with it…

views:
  - title: Floorplan
    path: floorplan
    theme: transparentblue
    type: panel
    icon: mdi:floor-plan
    badges: []
    cards:
      - type: vertical-stack
        cards:
          - type: horizontal-stack
            cards:
              - type: custom:floorplan-card
                full_height: true
                config:
                  image: /local/floorplan/zolder/zolder_opt.svg
                  stylesheet: /local/floorplan/38.css
                  log_level: info
                  console_log_level: info
                  defaults:
                    hover_action: hover-info
                    tap_action: more-info
                  rules:
                    - name: media players
                      entity: media_player.spotify_george
                      state_action:
                        action: call-service
                        service: floorplan.class_set
                        service_data: media_player media_player-${entity.state}
                      tap_action: more-info
                    - name: FAN set state
                      entity: fan.pure_hot_cool_link
                      state_action:
                        action: call-service
                        service: floorplan.class_set
                        service_data: fan-${entity.state}
                      tap_action:
                        action: toggle
                    - name: LIGHT set state
                      entities:
                        - light.canvas_wall_kantoor
                        - light.zoldertrap_led
                      tap_action: false
                      state_action:
                        action: call-service
                        service: floorplan.class_set
                        service_data: light-${entity.state}
                    - name: SWITCH set state
                      entities:
                        - switch.wall_plug_switch
                        - switch.light_switch_2_ch
                      tap_action: false
                      state_action:
                        action: call-service
                        service: floorplan.class_set
                        service_data: switch-${entity.state}
                    - entity: climate.pure_hot_cool_link
                      state_action:
                        action: call-service
                        service: floorplan.class_set
                        service_data: climate-${entity.state}
                      tap_action:
                        action: more-info
                    - name: Cover (zonwering) set state
                      entity: group.kantoor_zonwering
                      tap_action:
                        action: toggle
                      hold_action: more-info
                      state_action:
                        action: call-service
                        service: floorplan.class_set
                        service_data: cover-${entity.state}
                    - name: LIGHT overlay management
                      entities:
                        - light.canvas_wall_kantoor
                        - light.zoldertrap_led
                      tap_action:
                        action: toggle
                      hold_action: more-info
                      state_action:
                        action: call-service
                        service: floorplan.style_set
                        service_data:
                          element: >-
                            ${entity.entity_id.replace('light.',
                            'light_overlay.')}
                          style: |
                            >
                            if( entity.state !== "on" )
                                return "display: none;";
                            let hue = 0;
                            let sat = 0;
                            if(entity.attributes.hs_color )
                            {
                              hue = entity.attributes.hs_color[0];
                              sat = entity.attributes.hs_color[1];
                            }
                            if( sat < 10 )
                            {
                              return `
                                display: block;
                                filter:
                                  brightness(calc( ${entity.attributes.brightness} / 255));`
                            }
                            return `
                              display: block;
                              filter:
                                sepia(100%)
                                hue-rotate(calc( ${hue}deg - 55deg ))
                                brightness(calc( ${entity.attributes.brightness} / 255));`
                    - entities:
                        - switch.wall_plug_switch
                        - switch.light_switch_2_ch
                      tap_action:
                        action: toggle
                      hold_action: more-info
                      state_action:
                        action: call-service
                        service: floorplan.style_set
                        service_data:
                          element: >-
                            ${entity.entity_id.replace('switch.',
                            'switch_overlay.')}
                          style: |
                            >
                            if( entity.state !== "on" )
                                return "display: none;";
                            let hue = 0;
                            let sat = 0;
                            if(entity.attributes.hs_color )
                            {
                              hue = entity.attributes.hs_color[0];
                              sat = entity.attributes.hs_color[1];
                            }
                            if( sat < 10 )
                            {
                              return `
                                display: block;
                                filter:
                                  brightness(calc( ${entity.attributes.brightness} / 255));`
                            }
                            return `
                              display: block;
                              filter:
                                sepia(100%)
                                hue-rotate(calc( ${hue}deg - 55deg ))
                                brightness(calc( ${entity.attributes.brightness} / 255));`
                    - entities:
                        - sensor.z_wave_room_sensor_air_temperature
                        - sensor.pure_hot_cool_link_temperature
                      state_action:
                        - service: floorplan.text_set
                          service_data: >-
                            ${(entity.state !== undefined) ?
                            Math.round(entity.state * 10) / 10 + "°C" : ""}
                        - service: floorplan.class_set
                          service_data:
                            class: static-temp
                    - entity:
                        - sensor.z_wave_room_sensor_humidity
                      state_action:
                        - service: floorplan.text_set
                          service_data: >-
                            ${(entity.state !== undefined) ?
                            Math.round(entity.state * 10) / 10 + "%" :
                            "unknown"}
                        - service: floorplan.class_set
                          service_data:
                            class: static-temp
                    - entity:
                        - binary_sensor.kantoor_power_status
                      state_action:
                        - service: floorplan.class_set
                          service_data: '${(entity.state === "on") ? "pc-on" : "pc-off"}'
                    - entity: binary_sensor.node_6_home_security_motion_detection
                      state_action:
                        - service: floorplan.class_set
                          service_data: motion-${entity.state}
                    - entity: sensor.wasmachine_washer_machine_state
                      state_action:
                        - service: floorplan.class_set
                          service_data: was-${entity.state}
animated_background:
  default_url: https://cdn.flixel.com/flixel/ypy8bw9fgw1zv2b4htp2.hd.mp4
  entity: weather.home
  state_url:
    sunny:
      - https://cdn.flixel.com/flixel/hlhff0h8md4ev0kju5be.hd.mp4
      - https://cdn.flixel.com/flixel/zjqsoc6ecqhntpl5vacs.hd.mp4
      - https://cdn.flixel.com/flixel/jvw1avupguhfbo11betq.hd.mp4
      - https://cdn.flixel.com/flixel/8cmeusxf3pkanai43djs.hd.mp4
      - https://cdn.flixel.com/flixel/guwb10mfddctfvwioaex.hd.mp4
    partlycloudy:
      - https://cdn.flixel.com/flixel/13e0s6coh6ayapvdyqnv.hd.mp4
      - https://cdn.flixel.com/flixel/aorl3skmssy7udwopk22.hd.mp4
      - https://cdn.flixel.com/flixel/qed6wvf2igukiioykg3r.hd.mp4
      - https://cdn.flixel.com/flixel/3rd72eezaj6d23ahlo7y.hd.mp4
      - https://cdn.flixel.com/flixel/9m11gd43m6qn3y93ntzp.hd.mp4
      - https://cdn.flixel.com/flixel/hrkw2m8eofib9sk7t1v2.hd.mp4
    cloudy:
      - https://cdn.flixel.com/flixel/13e0s6coh6ayapvdyqnv.hd.mp4
      - https://cdn.flixel.com/flixel/aorl3skmssy7udwopk22.hd.mp4
      - https://cdn.flixel.com/flixel/qed6wvf2igukiioykg3r.hd.mp4
      - https://cdn.flixel.com/flixel/3rd72eezaj6d23ahlo7y.hd.mp4
      - https://cdn.flixel.com/flixel/9m11gd43m6qn3y93ntzp.hd.mp4
      - https://cdn.flixel.com/flixel/hrkw2m8eofib9sk7t1v2.hd.mp4
    mostlycloudy:
      - https://cdn.flixel.com/flixel/e95h5cqyvhnrk4ytqt4q.hd.mp4
      - https://cdn.flixel.com/flixel/l2bjw34wnusyf5q2qq3p.hd.mp4
      - https://cdn.flixel.com/flixel/rrgta099ulami3zb9fd2.hd.mp4
    clear-night:
      - https://cdn.flixel.com/flixel/x9dr8caygivq5secll7i.hd.mp4
      - https://cdn.flixel.com/flixel/v26zyfd6yf0r33s46vpe.hd.mp4
      - https://cdn.flixel.com/flixel/ypy8bw9fgw1zv2b4htp2.hd.mp4
      - https://cdn.flixel.com/flixel/rosz2gi676xhkiw1ut6i.hd.mp4
    fog:
      - https://cdn.flixel.com/flixel/vwqzlk4turo2449be9uf.hd.mp4
      - https://cdn.flixel.com/flixel/5363uhabodwwrzgnq6vx.hd.mp4
    rainy: https://cdn.flixel.com/flixel/f0w23bd0enxur5ff0bxz.hd.mp4

And the CSS that works with that:

@keyframes fade-in {
  from {
    opacity: 0;
  }
  to: {
    opacity: 1;
  }
}

@keyframes dash {
  to {
    stroke-dashoffset: 15000;
  }
}
@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
@keyframes speaker-pulse {
  0% {
    filter: unset;
    stroke-width: 1;
    stroke-opacity: 1;
  }
  100% {
    filter: unset;
    stroke-width: 6;
    stroke-opacity: 0;
  }
}
@keyframes active-pulse {
  0% {
    filter: unset;
    stroke-opacity: 1;
    stroke-width: 1px;
      filter:blur(1px);
  }
  15% {
    stroke-opacity: 1;
  }
  100% {
    filter: unset;
    stroke-opacity: 0.1;
    stroke-width: 15px;
      filter:blur(2px);
  }
}
@keyframes tv-glare {
  0% {
    opacity: 0.95;
  }
  100% {
    opacity: 0.1;
  }
}

svg, svg * {
  pointer-events: all !important;
  cursor: auto !important;
}
svg path {
  fill: inherit;
  stroke: inherit;
  stroke-width: inherit;
  stroke-opacity: inherit;
}

/*******************************************
Hover over, wat er gebeurt als je met de muis over een gebied schuift
********************************************/
.floorplan-shape:hover,
g.floorplan-hover > :not(text):hover,
g.floorplan-click > :not(text):hover,
g.floorplan-long-click > :not(text):hover,
:not(text).floorplan-hover:hover,
:not(text).floorplan-click:hover,
:not(text).floorplan-long-click:hover {
  stroke: #f78b07 !important;
  stroke-width: 5 !important;
  stroke-opacity: 0.8 !important;
    filter: blur(1px)
}

/************************************************
de kleur instelling van alle paths in de weergave
*************************************************/

/***********************************************
Afhankelijk van of een LIGHT of een SWITCH ON of OFF is wordt een andere afbeelding weergegeven
**************************************************/
#light-overlays image {
	display: none;
	mix-blend-mode: lighten;
  animation: 0.75s fade-in linear forwards;
}
#light-overlays image.light-on {
	display: block;
}
#light-overlays image.switch-on {
	display: block;
}

/***********************************************
Wat er met de lijnen rond gebieden gebeurt indien hover - aan of uit
***********************************************/
#areas {
  fill: none;
}
/*
g#areas path, g#entities path {
  filter: blur(1px)
}

g#entities path {
  stroke: blue;
  stroke-width: 4;
  stroke-opacity: 1;
  fill: none;
}

g#entities path {
  stroke: #f5a925;
  stroke-width: 3;
  stroke-opacity: 0.6;
  fill: none;
}
*/

/***********************************************
Als een light of switch GEACTIVEERD wordt, geeft dit feedback (stroke kleur) en worden de PATHs van de AREAs voorzien van een andere kleur rand
************************************************/
g path:active, g use:active, .light-on:active .switch-on:active .cover-closed:active, g#entities > g:active path:not(.touch-area)
{
  stroke: #00ff00 !important;
  stroke-width: 5;
  stroke-opacity: 0.9;
}
#areas .light-on {
  stroke-width: 5;
  stroke: #fcdf03;
  stroke-opacity: 0.8;
    filter: blur(2px);
}
#areas .light-off {
  stroke-width: 5;
  stroke: #f2dfc7;
  stroke-opacity: 0.6;
    filter: blur(1px);
}
#areas .switch-on {
  stroke-width: 5;
  stroke: #fcdf03;
  stroke-opacity: 0.8;
    filter: blur(2px);
}
#areas .switch-off {
  stroke-width: 5;
  stroke: #f2dfc7;
  stroke-opacity: 0.6;
    filter: blur(1px);
}

#areas .motion-on {
  fill: #ff00002e;
  stroke: red;
  stroke-width: 5px;
  stroke-opacity: 1;
  filter: unset;
  animation: fade-in 1s infinite alternate;
}

/********************************************
Wat er met de lijnen rond entities gebeurt indien aan of uit
**********************************************/
#entities path {
}
#entities .switch-on {
  stroke-width: 5;
  stroke: #fcdf03;
  stroke-opacity: 0.8;
    filter: blur(2px);
}
#entities .switch-off {
  stroke-width: 5;
  stroke: #f2dfc7;
  stroke-opacity: 0.6;
    filter: blur(1px);
}
/*
#entities .fan-on {
  stroke-width: 4;
  stroke: #eaff00;
  stroke-opacity: 0.8;
  fill: green;
  fill-opacity: 0.5;
  animation: fade-in 5s infinite alternate;
    filter: blur(2);
}
#entities .fan-off {
  stroke-width: 5;
  stroke: #f2dfc7;
  stroke-opacity: 0.6;
    filter: blur(2);
}
*/

#entities .pc-on {
  fill: #00ff00;
  fill-opacity: 0.4;
  stroke-width: 4;
  stroke: #0bfc03;
  stroke-opacity: 0.8;
    filter: blur(1px);
}
#entities .pc-off {
  stroke-width: 5;
  stroke: #97a197;
  stroke-opacity: 0.6;
    filter: blur(1px);
}
#entities .was-stop,
#entities .was-finish {
  stroke: grey;
  stroke-width: 4px;
  stroke-opacity: 0.7;
}
#entities .was-run {
  animation: 3s active-pulse infinite;
  stroke: blue;
  fill: blue;
  fill-opacity: 0.4;
}

#entities .cover-closed {
  stroke-width: 5;
  stroke: #ab2503;
  stroke-opacity: 0.8;
    filter: blur(2px);
  fill: grey;
  fill-opacity: 0.9;
}
#entities .cover-open {
  stroke-width: 5;
  stroke: #f2dfc7;
  stroke-opacity: 0.6;
    filter: blur(1px);
}

#entities .climate-cool {
  fill: blue;
  fill-opacity: 0.5;
  stroke: var(--cool-color, blue);
  stroke-opacity: 0.5;
  stroke-width: 5;
    filter: blur(5px);
  filter: unset;
  animation: fade-in 3s infinite alternate;
  }
#entities .climate-heat {
  fill: #ff8100;
  fill-opacity: 0.5;
  stroke: #ff8100;
  stroke-opacity: 1;
  stroke-width: 3;
    filter: blur(5px);
  filter: unset;
  animation: fade-in 3s infinite alternate;
}
#entities .climate-off {
  stroke: #97a197;
  stroke-width: 3;
  stroke-opacity: 0.6;
    filter: blur(2px);
}
#entities .media_player.media_player-idle,
#entities .media_player.media_player-standby,
#entities .media_player.media_player-paused {
  stroke: var(--paper-item-icon-active-color);
  stroke-width: 4px;
  stroke-opacity: 0.7;
}
#entities .media_player.media_player-playing {
  animation: 2s active-pulse infinite;
  stroke: var(--paper-item-icon-active-color);
}
/**************************************
Temperature text
***************************************/
.static-temp, .static-temp tspan {
  fill: #d4c8ba;
  opacity: 0.7;
  text-shadow: 2px 2px 5px #120c04;
}

/********************************************
Binary sensors oftewel de motion sensoren
************************************************/
/*svg#floorplan.show-motion-off .motion {
  display: none;
}
svg#floorplan.show-motion-on .motion-on {
  fill: red;
  stroke: white;
  stroke-width: 4;
  stroke-opacity: 0.8;
  filter: unset;
  animation: fade-in 1s infinite alternate;
}
*/

/*
.binary-sensor-on {
  fill: #f70707 !important;
  fill-opacity: 0.5;
  stroke: red !important;
  stroke-width: 8
}
.binary-sensor-off {
  fill: #8c765b !important;
  transition: fill 5s ease;
}
*/

/* Animation */

.spinning {
  animation-name: spin;
  animation-duration: 5s;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
  transform-origin: 50% 50%;
  transform-box: fill-box;
}

/* Switches
.switch-on {
  fill: blue !important;
}

.switch-off {
  fill: white !important;
}

stroke-dasharray: 100;
animation: dash 200s linear;
*/

And in the spirit of full disclosure, here’s the SVG file that’s loaded:

<?xml version="1.0" encoding="UTF-8"?>
<svg width="1920" height="1080" version="1.1" viewBox="0 0 1920 1080" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <g id="background">
    <image id="main-background" width="1920" height="1080" href="/local/floorplan/zolder/zolder-basis.png" preserveAspectRatio="none" xlink:href="file:///Z:/3D/zolder/zolder-basis.png"/>
    <g id="light-overlays">
      <image id="light_overlay.canvas_wall_kantoor" width="1920" height="1080" href="/local/floorplan/zolder/zolder-0002.png" preserveAspectRatio="none" xlink:href="file:///Z:/3D/zolder/zolder-0002.png"/>
      <image id="switch_overlay.light_switch_2_ch" width="1920" height="1080" href="/local/floorplan/zolder/zolder-0004.png" preserveAspectRatio="none" xlink:href="file:///Z:/3D/zolder/zolder-0004.png"/>
      <image id="switch_overlay.wall_plug_switch" width="1920" height="1080" href="/local/floorplan/zolder/zolder-0001.png" preserveAspectRatio="none" xlink:href="file:///Z:/3D/zolder/zolder-0001.png"/>
      <image id="light_overlay.zoldertrap_led" width="1920" height="1080" href="/local/floorplan/zolder/zolder-0003.png" preserveAspectRatio="none" xlink:href="file:///Z:/3D/zolder/zolder-0003.png"/>
      <image id="group_overlay.kantoor_zonwering" width="1920" height="1080" href="/local/floorplan/zolder/zolder-0005.png" preserveAspectRatio="none" xlink:href="file:///Z:/3D/zolder/zolder-0005.png"/>
    </g>
  </g>
  <g id="areas">
    <g id="area.kantoor_george">
      <path id="path429" d="m932.85 338.68-4.0914-98.195 2.8474-4.9254 126.26-31.67-8.1446-23.396 215.6-58.802 155.29 363.85-53.615 72.03-330.33 97.361-3.4443 5.1241-29.458-91.802-0.4546-9.5467z" fill="none" stroke="#000" stroke-width="1px"/>
      <use xlink:href="#path429"/>
      <use id="binary_sensor.node_6_home_security_motion_detection" xlink:href="#path429"/>
      <use xlink:href="#path429"/>
      <use id="light.canvas_wall_kantoor" xlink:href="#path429"/>
    </g>
    <g id="area.kantoor">
      <path id="path431" d="m1003.3 558.71 0.4546 9.5467-115.68 33.079-2.2863-6.0732-154.6 44.07-15.601-34.804-5.477 1.6237-0.0118 4.8037-91.085 25.378-3.595-3.1652-4.4715 1.0462 0.42719 4.7652 3.7503 4.6506 2.9709 19.306 0.22113 6.1821-132.01 39.49-0.49922-3.3989 8.0586-2.6878-63.561-306.07 275.75-240.85 13.549 49.297 56.582-12.489 20.02 67.549 130.33-34.428 1.2769 4.5066 5.0218 108.64z" fill="none" stroke="#000" stroke-width="1px"/>
      <use xlink:href="#path431"/>
      <use id="switch.light_switch_2_ch" xlink:href="#path431"/>
    </g>
    <g id="area.zoldertrap">
      <path id="path433" d="m888.09 601.34 60.088 200.69 0.65299 5.4486 121.06-36.307 1.3181-7.0263-34.538-109.21-3.4443 5.1241-29.458-91.802z" fill="none" stroke="#000" stroke-width="1px"/>
      <use xlink:href="#path433"/>
      <use id="light.zoldertrap_led" xlink:href="#path433"/>
    </g>
    <g id="area.washok">
      <path d="m490.38 707.28 1.0004 3.6998 4.1473 6.8579 45.683 212.51 407.62-122.88-0.65299-5.4486-60.088-200.69-2.2863-6.0732-154.6 44.07-15.601-34.804-5.477 1.6237-0.0118 4.8037-91.085 25.378-3.595-3.1652-4.4715 1.0462 0.42719 4.7652 3.7503 4.6506 3.192 25.488z" fill="none" stroke="#000" stroke-width="1px"/>
    </g>
  </g>
  <g id="entities" fill="none">
    <path id="group.kantoor_zonwering" d="m1409.7 477.45-36.809 48.526-132.4-320.73 22.905-70.459z" stroke="#000" stroke-width="1px"/>
    <path id="fan.pure_hot_cool_link" d="m991.68 472.21 17.998-3.945c0.3727 0.80556 0.1169-4.1203 0.1169-4.1203 0.4606 0.47643 0 0 0 0 2.1045 0.26975 5.5449-1.0471 5.5449-1.0471l3.3212-4.3418c1.7613-9.6469 0.9992-13.206 0.9992-13.206-0.6853-2.4192-0.066-0.98012-2.0559-7.2575 0 0-1.2012-5.6166-10.55-14.417 0 0-1.5506-1.2391-3.9786-0.30127 0 0-2.7358 1.2084-3.7711 3.7548-1.2449 0.25476-0.92758 4.3402-0.92758 4.3402s0.11055 2.4417 0.36319 5.4509l-12.992 3.6962 0.47998 2.5996-2.1603 0.59767c-0.8373 2.2465 0.62446 10.404 4.2458 15.551l-0.074 3.4793z" stroke="#b32800" stroke-width="1.0016"/>
    <path id="climate.pure_hot_cool_link" d="m991.68 472.21 17.998-3.945c0.3727 0.80556 0.1169-4.1203 0.1169-4.1203 0.4606 0.47643 0 0 0 0 2.1045 0.26975 5.5449-1.0471 5.5449-1.0471l3.3212-4.3418c1.7613-9.6469 0.9992-13.206 0.9992-13.206-0.6853-2.4192-0.066-0.98012-2.0559-7.2575 0 0-1.2012-5.6166-10.55-14.417 0 0-1.5506-1.2391-3.9786-0.30127 0 0-2.7358 1.2084-3.7711 3.7548-1.2449 0.25476-0.92758 4.3402-0.92758 4.3402s0.11055 2.4417 0.36319 5.4509l-12.992 3.6962 0.47998 2.5996-2.1603 0.59767c-0.8373 2.2465 0.62446 10.404 4.2458 15.551l-0.074 3.4793z" stroke="#b32800" stroke-width="1.0016"/>
    <path id="binary_sensor.kantoor_power_status" d="m1214.7 246.53 13.099 35.521 12.858-3.3753-6.9112 20.573-12.617 3.0538-10.857-28.798 4.4281-26.975 12.537-3.0538 13.582 35.199-13.019 3.3753-6.6701 20.252 6.6701-20.252z" stroke="#000" stroke-width="1px"/>
    <path id="switch.wall_plug_switch" d="m1213.8 207.02 22.662-6.4291 137.74 332.71-25.234 7.072z" stroke="#000" stroke-width="1px"/>
    <path id="media_player.spotify_george" d="m1085.9 230.37 120.7-32.845-8.8648 38.641-118.54 31.027z" stroke="#000" stroke-width="1px"/>
    <path id="sensor.wasmachine_washer_machine_state" d="m840.11 725.32 20.172 67.817-20.172-67.817 6.5444 33.488 16.413 51.751 64.44-19.321-64.44 19.321-2.7854-17.421 66.203-18.947 1.0229 17.048-1.0229-17.048-20.457-67.964z" stroke="#000" stroke-width="1px"/>
  </g>
  <g id="sensors">
    <g fill="#000000" font-family="sans-serif" font-size="40px">
      <text id="sensor.z_wave_room_sensor_air_temperature" transform="rotate(-15 921.82 806.01)" x="1290" y="673" style="line-height:1.25;shape-inside:url(#rect58646);white-space:pre" xml:space="preserve"/>
      <text id="sensor.z_wave_room_sensor_humidity" transform="rotate(-15 1299.8 859.94)" x="1315" y="538" style="line-height:1.25;shape-inside:url(#rect58646);white-space:pre" xml:space="preserve"/>
      <text id="sensor.pure_hot_cool_link_temperature" transform="rotate(-15 983.14 485.09)" x="1040" style="line-height:1.25;shape-inside:url(#rect9182);white-space:pre" Y="470" xml:space="preserve"/>
    </g>
  </g>
</svg>

Feeling pretty good about the progress so far.
I’ve been able to get the temperature showing from both a room sensor and the dyson hot+cool fan. Also the humidity is showing and i’ve got css animations working for music playing, PC on, motion detected, washing machine operational, lights on/off, dyson fan heating/cooling so yay…

As you’ll notice there’s still a lot of doubling and trial and error in here :wink: It’s a work in progress.

Thanks to the lengthy tutorial from BitBorn i’ve been able te reconstruct most of what he did, somewhat that is.

Now for my questions:

  1. did I mess it up completely? In other words, have i gotten basics wrong somewhere?
  2. Is there a way to disable the NaNC when the Dyson fan is off? When it’s off it doens’t report the temperature and NaNC is shown on the floorplan as you can see on the screenprints :frowning:
  3. I can’t seem to find a way to change the colors on the temperature that’s being displayed dependent on the current temperature, how do I do that?
  4. How do I use extra cards/info like the honeycomb menu to open up?
  5. How do i place icons like a camera, motion sensor or something from yaml into the floorplan? Or do I have to use the SVG for that?

I don’t have time at the moment to have a close look but some I can help with straight away. Before I get to that can I advertise the github discussion area that is great for complex questions like this: https://github.com/ExperienceLovelace/ha-floorplan/discussions

  1. I don’t know which entity is the Dyson fan but you should be able to use the same shorthand javascript that you have for sensor.pure_hot_cool_link_temperature there you are testing for undefined but you will change that to whatever the state is when it is off.

            - entities:
                - sensor.wupws_temp
              name: Colour Coded Sensors
              state_action:
                - service: floorplan.text_set
                  service_data: '${entity.state != "unavailable" ? Math.round(entity.state) + "°" : "?"}'
                - service: floorplan.class_set
                  service_data: |
                    >
                      var temp = parseFloat(entity.state.replace("°", "")); 
                      if (temp < 10) return "temp-low"; 
                      else if (temp < 30) return "temp-medium"; 
                      else return "temp-high";
  1. Do you mean dynamically change an icon based on state? If so have a look at my image_set example here https://github.com/ExperienceLovelace/ha-floorplan/discussions/91

If you mean show a camera image on tap then just make the tap_action service more-info

Hey @OzGav thanks for the quick reply

  1. I’ll also post remaining questions on there.
  2. As for the fan, the dyson fan IS that pure hot and cool fan where it’s showing NaNC at the moment. I can’t seem to disable that showing when there’s no temperature being reported other then NaNC.
  3. Super thanks for the temp var code, I implemented it straight away and added the corresponding CSS code to it, working like a charm now:
                    - entities:
                        - sensor.z_wave_room_sensor_air_temperature
                        - sensor.pure_hot_cool_link_temperature
                      state_action:
                        - service: floorplan.text_set
                          service_data: >-
                            ${(entity.state !== undefined) ?
                            Math.round(entity.state * 10) / 10 + "°C" : "OFF"}
                        - service: floorplan.class_set
                          service_data:
                            class: static-temp
                        - service: floorplan.class_set
                          service_data: |
                            >
                              var temp = parseFloat(entity.state.replace("°", "OFF")); 
                              if (temp < 17) return "temp-low"; 
                              else if (temp < 22) return "temp-medium"; 
                              else if (temp < 25) return "temp-medium-high"; 
                              else return "temp-high";
.temp-low, .temp-low tspan {
  fill: #c0d3ed;
  opacity: 0.7;
  text-shadow: 2px 2px 5px #00429e;
}
.temp-low, .temp-medium tspan {
  fill: #bcedb2;
  opacity: 0.7;
  text-shadow: 2px 2px 5px #20b004;
}
.temp-low, .temp-medium-high tspan {
  fill: #e0d0a8;
  opacity: 0.7;
  text-shadow: 2px 2px 5px #b07c04;
}
.temp-low, .temp-high tspan {
  fill: #e0a8a8;
  opacity: 0.7;
  text-shadow: 2px 2px 5px #f70000;
}
  1. I’ll have a look at that. But the thing is, I don’t know how to get an icon in the floorplan :frowning: :flushed:
  2. this would mean that i have a camera-item like in an icon that i can then select, hence the previous question :video_camera:

Yes so you can just add icons to your SVG (if using Inkscape they can be SVG or PNG) and then, using the camera as an example, just give the icon the ID of camera.yourcam and then in your yaml you just add an entity of camera.yourcam and tap_action of more-info

As for 2 you would do something like

${(entity.state !== “NaNC”) ? Math.round(entity.state * 10) / 10 + “°C” : “OFF”}

I don’t have the exact code with my as I am on the iPad but it will be something like that. You just need to put the exact wording of the sensor state when it is off