Your Home Digital Twin: Interactive floor 3d plan

Hello Mathieu, while the card is working wiht obj and glb format produced by any modeling tool, it performs the best when you use Sweethome3d and even more when you use the ExportToHass plugin. Why that ? Because each modeling tool has its own way to export to standard formats and many have bugs or their own interpretation how objects should be exported. For instance, all modeling tools,rename the objects when re-exporting after a change in the model. The HA card is very sensitive to those changes because it uses the object names to bind to HA entities; this is the main reason why I did the plugin in sweethome3d, but I cannot do it for all modeling tools and not all of them have easy ways to create plugins.
Adding more than 2 entities should not cause problems. The only enity type that has a number limit is the lights; the error is probably due to other issues, not the number of entities. Please give more info (console logs, yaml config of the card, screenshot, etc)
Note that Glb format is also very experimental.
The json object list is optional. It is an output of the ExportToHass plugin in sweethome3d. It only becomes mandatory when you want to play with multi level models in Sweethome3d (it is optional in all other cases).

"Hi, first of all thank you for this amazing card. The doors opening and the color-synced lights were nice surprises! They’re the kind of thing that makes this whole home automation thing worth the countless invested hours. The temperature displayed with a transparent box and overlay is nice too. But alas, I do have a few issues… though I am not sure if it is me, or the code. So far these issues seem to persist:

#1. I seem to have a problem with the text feature. I can’t get state text to appear or any other text for that matter for any entity and its states! (which is weird because the color: feature works just fine with those same entities, and entitiy states). I have tried NO input for the attribute: selection, which I am assuming is supposed to display the state. I have tried the app_name: attribute, and even the freindly_name: just to get it to display something. I have tried displaying it on a glass window in case the image is displayed on the wrong side of the surface. I have tried deleting all my other entities from the 3d card configuration to see if there was some sort of conflict. I have tried loading both the .glb and .obj. I have spent about 5 hours so far just on this issue alone, with help from ChatGPT and I still can’t figure it out.

#2 This issue is basically the same, but with the show: and hide: features instead, and the addition of errors preventing the model from rendering. But this gets a little weirder… If I load the UI with the entity in the desired state for the ‘hide’ or ‘show’ feature to work, only then will the errors appear. Furthermore, if the desired state is not achieved at the time the UI loads, the UI will load just fine, with the model entity working as expected, disappearing and appearing as expected with the state changes.

#3 Having 2 levels, I use the HASS plugin for SweetHome, and the overlay for the level selection is far too small, and the actual button doesn’t seem to line up exactly with the UI. I have been left many times frustrated with trying to select the right level. It would be nice to customize those buttons a bit.

#4 This one is more of a feature request. It would be nice to also have a mdi:run icon show above/on the room floor. Obviously for room presence detection. I tried just painting the floor a color instead, but when using the temperature room feature, it’s very hard to see, no matter what color I choose.

#5 Another request: maybe the addition of a camera_postion: argument to the zoom: feature. I found it extremely difficult to get the right angle, when relying on the position of the camera to be determined by locking onto and setting a distance of an object. Something that would help a bit if it’s easier to implement than the above mentioned, is the addition of elevation as well as distance, to help get that right camera position.

#6 A few other requests might include: animations more devices, like waves for air cons and soundwaves for speakers. But these probably wouldn’t be necessary with the icon request I mentioned earlier.

#7 Last request: some of us can load their models on low powered devices, like my Samsung A8 tablet. But loading the whole thing at once can be a miserable experience. If there was a way to choose which floor or section to load at first, and toggle between them easily (leaving only 1 level or section displayed at a time), it would make the experience usable on many more devices.

Anyway thanks again for the amazing card! I cant see myself not using it now, even with the bugs i mentioned.
I am available to troubleshoot if needed, but my time and knowledge about code is extremely limited, I rely heavily on GPT to write what i can.

BTW: If its relevant i am running hassOS, and these are the only logs i can find…

Logger: frontend.js.latest.202212131
Source: components/system_log/__init__.py:256
First occurred: 11:49:47 AM (26 occurrences)
Last logged: 11:56:44 AM

http://homeassistant.local:8123/home-family-tab/3d-view?edit=1:0:0 Uncaught
http://homeassistant.local:8123/home-family-tab/3d-view:0:0 Uncaught
http://homeassistant.local:8123/developer-tools/state:0:0 Uncaught

and my working ui config is here

type: custom:floor3d-card
path: /local/Home_3D_Floor_Plan_V7
name: Home
objfile: home.glb
lock_camera: 'no'
header: 'no'
click: 'yes'
overlay: 'no'
backgroundColor: '#000000'
hideLevelsMenu: 'no'
globalLightPower: '0.7'
shadow: 'no'
extralightmode: 'no'
show_axes: 'no'
sky: 'no'
overlay_bgcolor: transparent
overlay_alignment: top-left
overlay_width: '33'
overlay_height: '20'
north:
  x: -1
  z: 0
camera_position:
  x: -798.4686843957337
  'y': 2999.705681430588
  z: 187.13911849970634
camera_rotate:
  x: -100.27666287624484
  'y': -0.06338710578585374
  z: -0.20614306531041865
camera_target:
  x: -608.930533661716
  'y': 141.7872224966762
  z: -678.5812746304193
object_groups:
  - object_group: stair_case_full
    objects:
      - object_id: Curve_staircase_19
      - object_id: Curve_staircase_31
      - object_id: Curve_staircase_23
      - object_id: Curve_staircase_26
      - object_id: Curve_staircase_15
      - object_id: Curve_staircase_5
      - object_id: Curve_staircase_32
      - object_id: Curve_staircase_14
      - object_id: Curve_staircase_9
      - object_id: Curve_staircase_7
      - object_id: Curve_staircase_16
      - object_id: Curve_staircase_18
  - object_group: diningroom_blinds
    objects:
      - object_id: Blind_1_2
      - object_id: Blind_2_2
      - object_id: Blind_3_2
entities:
  - entity: media_player.samsung_q7_series_65
    type3d: color
    object_id: TV_3
    colorcondition:
      - state: 'on'
        color: blue
      - state: 'off'
        color: black
    action: more-info
  - entity: sensor.living_room_temperature_sensor_a_c_temperature_2
    type3d: room
    object_id: room_13_1
    room:
      transparency: '80'
      label_text: state
      label: 'yes'
    colorcondition:
      - color: red
        state: hot
      - color: green
        state: cool
    entity_template: '[[[ if ($entity > 27) { "hot" } else { "cool" } ]]]'
    action: overlay
  - entity: sensor.master_bedroom_temperature_sensor_temperature
    type3d: room
    object_id: room_16_1
    room:
      transparency: '80'
      label_text: state
      label: 'yes'
    colorcondition:
      - color: red
        state: hot
      - color: green
        state: cool
    entity_template: '[[[ if ($entity > 27) { "hot" } else { "cool" } ]]]'
    action: overlay
  - entity: sensor.temperature_humidity_sensor_3_temperature
    type3d: room
    object_id: room_10_1
    room:
      transparency: '80'
      label_text: state
      label: 'yes'
    colorcondition:
      - color: red
        state: hot
      - color: green
        state: cool
    entity_template: '[[[ if ($entity > 27) { "hot" } else { "cool" } ]]]'
    action: overlay
  - entity: sensor.luca_s_bedroom_temperature_sensor_temperature
    type3d: room
    object_id: room_14_1
    room:
      transparency: '80'
      label_text: state
      label: 'yes'
    colorcondition:
      - color: red
        state: hot
      - color: green
        state: cool
    entity_template: '[[[ if ($entity > 27) { "hot" } else { "cool" } ]]]'
    action: overlay
  - entity: binary_sensor.ensuite_contact_sensor
    type3d: door
    door:
      side: left
      doortype: swing
      direction: outer
    object_id: Ensuite_Door_9
  - entity: binary_sensor.walk_in_contact_sensor_2
    type3d: door
    door:
      side: left
      direction: inner
      doortype: swing
    object_id: Walk_In_Door_9
  - entity: binary_sensor.bathroom_contact_sensor_2
    type3d: door
    door:
      side: left
      direction: outer
      doortype: swing
    object_id: Bathroom_Door_9
  - entity: binary_sensor.toilet_contact_sensor_2
    type3d: door
    door:
      doortype: swing
      side: left
      direction: outer
    object_id: Toilet_Door_9
  - entity: binary_sensor.front_door_contact_sensor_2
    type3d: door
    door:
      side: right
      direction: inner
      doortype: swing
    object_id: Door_9
  - entity: light.master_bedroom_light
    type3d: light
    object_id: Master_Bedroom_Light_2
    light:
      lumens: '800'
      decay: '2'
  - entity: light.ensuite_light
    type3d: light
    object_id: Ensuite_Light_2
    light:
      lumens: '1000'
      decay: '2'
      distance: '200'
      shadow: 'no'
  - entity: light.bathroom_light
    type3d: light
    object_id: Bathroom_Light_2
    light:
      lumens: '600'
      decay: '2'
  - entity: light.hallway_light
    type3d: light
    object_id: Hallway_light_2
    light:
      lumens: '800'
      decay: '6'
  - entity: light.toilet_light
    type3d: light
    object_id: Toilet_Light_2
    light:
      lumens: '800'
      decay: '5'
  - entity: light.luca_s_bedroom_light
    type3d: light
    object_id: Lucas_Bedroom_Light_2
    light:
      lumens: '800'
      decay: '2'
  - entity: light.stairs_strip_light_2
    type3d: light
    object_id: Stairs_Light_2
    light:
      lumens: '50000'
      decay: '4'
      distance: '300'
  - entity: light.back_patio_light
    object_id: Livingroom_Light_2
    type3d: light
    light:
      lumens: '4000'
      angle: '90'
      light_target: room_13_1
      distance: '600'
      vertical_alignment: bottom
  - entity: light.walk_in_light
    type3d: light
    object_id: Walk_In_Light_2
    light:
      lumens: '2000'
      light_target: room_15_1
      distance: '400'
      angle: '90'
      vertical_alignment: middle
      decay: '2'
  - entity: light.kitchen_light
    type3d: light
    object_id: Kitchen_Light_2
    light:
      lumens: '5000'
      vertical_alignment: middle
      distance: '300'
      light_target: room_2_1
      decay: '1'
      angle: '90'
      shadow: 'no'
  - entity: light.laundry_light
    type3d: light
    object_id: Laundry_Light_2
    light:
      lumens: '2000'
      distance: '398'
      light_target: Washbasin_with_cabinet_7
      angle: '90'
  - entity: light.front_patio_light
    type3d: light
    object_id: Front_Patio_Light_5
    light:
      lumens: '2000'
  - entity: light.zac_s_bedroom_light
    type3d: light
    object_id: Zacs_Bedroom_Light_2
    light:
      lumens: '2000'
      distance: '400'
      decay: '2'
  - entity: camera.blue_iris_amcrest_front_door_camera
    type3d: camera
    object_id: Amcrest_Front_Door_6
  - entity: camera.blue_iris_amcrest_back_door_camera
    type3d: camera
    object_id: Amcrest_Camera_Back_Door_6
  - entity: camera.blue_iris_sonoff_livingrooom_camera
    type3d: camera
    object_id: Sonoff_Camera_Livingroom_13
  - entity: camera.luca_s_camera
    type3d: camera
    object_id: Nest_Camera_Luca_7
  - entity: camera.kitchen_display
    type3d: camera
    object_id: Nest_Display_Kitchen_2
  - entity: binary_sensor.living_room_occupancy
    type3d: color
    object_id: room_13_1
    colorcondition:
      - state: 'on'
        color: '#000000'
  - entity: binary_sensor.pir_master_bedroom
    type3d: color
    object_id: room_16_1
    colorcondition:
      - state: 'on'
        color: '#000000'
  - entity: binary_sensor.pir_laundry
    type3d: color
    object_id: room_3_1
    colorcondition:
      - state: 'on'
        color: '#000000'
  - entity: binary_sensor.pir_kitchen_2
    type3d: color
    object_id: room_2_1
    colorcondition:
      - state: 'on'
        color: '#000000'
  - entity: binary_sensor.pir_bottom_stairs_2
    type3d: color
    object_id: <stair_case_full>
    colorcondition:
      - state: 'on'
        color: '#000000'
  - entity: binary_sensor.pir_top_stairs_2
    type3d: color
    object_id: <stair_case_full>
    colorcondition:
      - state: 'on'
        color: '#000000'
  - entity: binary_sensor.pir_top_stairs_2
    type3d: color
    object_id: room_10_1
    colorcondition:
      - state: 'on'
        color: '#000000'
  - entity: binary_sensor.pir_luca_s_bedroom_2
    type3d: color
    object_id: room_14_1
    colorcondition:
      - state: 'on'
        color: '#000000'
    action: default
  - entity: binary_sensor.pir_ensuite
    type3d: color
    object_id: room_16_1
    colorcondition:
      - state: 'on'
        color: '#000000'
  - entity: binary_sensor.pir_aqara_bathroom
    type3d: color
    object_id: room_7_1
    colorcondition:
      - state: 'on'
        color: '#000000'
  - type3d: color
    object_id: room_11_1
    colorcondition:
      - state: 'on'
        color: '#000000'
    entity: pir_aqara_ensuite
  - entity: pir_aqara_toilet
    type3d: color
    object_id: room_8_1
    colorcondition:
      - state: 'on'
        color: '#000000'
  - entity: binary_sensor.marks_bed_sensor
    action: more-info
    type3d: color
    object_id: Bed_18
    colorcondition:
      - color: yellow
        state: 'off'
mtlfile: home.mtl
objectlist: home.json
selectionMode: 'no'
editModeNotifications: 'yes'
zoom_areas:
  - zoom: Livingroom Cameras
    object_id: Sonoff_Camera_Livingroom_13
    distance: '50'
    rotation:
      x: -0.4295283840084365
      'y': 600.9757211209288
      z: 400.36254777125407
    direction:
      x: -608.930533661716
      'y': 141.7872224966762
      z: -2047.716542480854
  - zoom: Livingroom Cameras test
    object_id: Livingroom_Light_2
    distance: '130'
    rotation:
      x: -2.4632749935981453
      'y': -1.0750672405640795
      z: -2.524936951300191
    direction:
      x: -233.1642459094933
      'y': -57.951761908927885
      z: -103.1472103125235

Hello @SomeoneSinister I acknowledge your problems, give me a little time to answer as your post is very articulated.

No worries, take your time.
If there is anything I can help with, or if I failed to explain things correctly, just let me know.

I have only been in the home automation game for about 1 year, and there is a lot I’m still learning.

I have converted to GLB, file now weighing in at 243MB so it’s better.

FYI ~30-50 MB GLB file is all my systems (M1 MacBook Pro with 16 GB RAM & Windows 11 on Ryzen 7 PRO 4750GE with built-in Radeon Graphics with 32 GB RAM) can handle. I can still make pretty complex models with judicious use of furnishings.

Evening all,

I’ve been playing with this card for the last few days and it very (well done Adizanni)

Is there a way to have the entities call a service rather than turn a light on and off. I have this card nested in a vertical stack, conditional card and need to be able to switch to other cards in the stack.

ok just spotted the section on this in the docs. Still not able to get it to work though.

My code is

>   - entity: input_select.floorplan_floor
>     object_id: Garage_light_1
>     type3d: gesture
>     gesture:
>       domain: input_select
>       service: input_select.select_option
>       data: 
>        entity_id: input_select.floorplan_floor
>        option: TV
>     action: default

I get a 'key not provided @ data ‘service’ message.

Once again excellent work on this card

Ok made some progess

new code is

  - entity: input_select.floorplan_floor
    object_id: Door_9
    type3d: gesture
    gesture:
      domain: input_select
      service: select_option
      data: 
       entity: input_select.floorplan_floor
       option: TV

which gives me an

key not provided @ data ‘option’

error which is at least a step forward from the service error.

If I change ‘service: select_option’ to ‘service: select_first’ it works fine. It must be something Ihave wrong after the service: line but i can’t see what.

Please Help.

Hello @D4VEW557 , I am really late in replying. I’m worried that the data section in the service call is not supported. You can only call a service that requires the entity as a parameter (example toggle).

Hi There.
Thanks for the reply. I explains why I couldn’t get it working. Just means a bit of a rethink of my setup.

I am however having another issue.

It is with a door. I have created a group for all the door components. If I use the hide option the door disappears so the group is working fine.

However if I try to use the door option I get the following error

Logger: frontend.js.latest.202301100
Source: components/system_log/init.py:256
First occurred: 16:55:50 (90 occurrences)
Last logged: 18:28:13

http://192.168.1.111:8123/hacsfiles/floor3d-card/floor3d-card.js?hacstag=361776538151:2357:4587 Uncaught Error
http://192.168.1.111:8123/lovelace/test?edit=1:0:0 Uncaught

my config is

type: custom:floor3d-card
path: /local/new-home/3d card/livroom/
name: Home
objfile: home.obj
lock_camera: 'no'
header: 'yes'
click: 'no'
overlay: 'no'
backgroundColor: '#aaaaaa'
hideLevelsMenu: 'no'
globalLightPower: '0.8'
shadow: 'yes'
extralightmode: 'no'
show_axes: 'no'
sky: 'no'
overlay_bgcolor: transparent
overlay_fgcolor: black
overlay_alignment: top-left
overlay_width: '33'
overlay_height: '20'
north:
  x: 0
  z: -1
camera_position:
  x: 609.3072605703628
  'y': 905.5330092468828
  z: 376.66437610591277
camera_rotate:
  x: -1.0930244719682243
  'y': 0.5200808414019678
  z: 0.7648717152512469
camera_target:
  x: 37.36890424945437
  'y': 18.64464320782064
  z: -82.55051697031719
object_groups:
  - object_group: drd
    objects:
      - object_id: Door_GlassPanels_17_342
      - object_id: Door_GlassPanels_14_339
      - object_id: Door_GlassPanels_15_340
      - object_id: Door_GlassPanels_16_341
      - object_id: Door_GlassPanels_28_353
      - object_id: Door_GlassPanels_13_338
      - object_id: Door_GlassPanels_10_335
      - object_id: Door_GlassPanels_11_336
      - object_id: Door_GlassPanels_9_334
      - object_id: Door_GlassPanels_8_333
      - object_id: Door_GlassPanels_6_331
      - object_id: Door_GlassPanels_7_332
      - object_id: Door_GlassPanels_20_345
      - object_id: Door_GlassPanels_24_349
      - object_id: Door_GlassPanels_21_346
      - object_id: Door_GlassPanels_26_315
      - object_id: Door_GlassPanels_27_325
      - object_id: Door_GlassPanels_12_337
      - object_id: Door_GlassPanels_24_349
      - object_id: Door_GlassPanels_29_354
      - object_id: Door_GlassPanels_15_340
      - object_id: Door_GlassPanels_19_344
      - object_id: Door_GlassPanels_18_343
      - object_id: Door_GlassPanels_7_332
      - object_id: Door_GlassPanels_14_339
      - object_id: Door_GlassPanels_27_352
      - object_id: Door_GlassPanels_26_351
      - object_id: Door_GlassPanels_22_347
      - object_id: Door_GlassPanels_23_348
      - object_id: Door_GlassPanels_25_350
entities:
  - entity: input_boolean.floorplan_test
    object_id: PolyMesh_1_2_2_272
    type3d: light
    action: default
    light:
      shadow: 'yes'
  - entity: input_boolean.floorplan_test
    type3d: door
    object_id: <drd>
    action: default
    door:
      doortype: slide
      side: right
      percentage: '50'
zoom_areas:
  - zoom: ''
mtlfile: home.mtl
objectlist: home.json
selectionMode: 'no'
editModeNotifications: 'yes'

Any help is always appreciated and once a again excellent work on this project.

Hi, i might be able to help here. (I could be wrong with all of this) but I believe the door you are using might not support opening and closing.
I haven’t searched extensively, but i have found only 3 doors by default, that open and close.
also I don’t believe you are meant to group the door parts, you just reference the panel that you want to swing or slide. Try, not using the group, and pick a panel that you want to slide or swing.
there will be some artifacts, like the door handles not moving, and being visible where the door panel used to be. but if you pick the right door you have to look really hard to see it, and its really easy to forget about if you want to.

note: I just tried it now and I was right. you are not meant to use the door panels as a group, when I just tried it then the door swing pivoted from the middle of the door rather than the end.
I guess this was due to the pivot point being changed by the door handle’s. (which i thought was handled by a json or mtl file, but apparently not)
I havnt tried it but it would seem like it would make a sliding door not open at all, due to the other panels influencing it.

edit: i am stupid, you can just use the hide feature to disappear those artifacts anyway.

@SomeoneSinister got part of the problem. In a door you have to either put a panel or a hinge attribute.
When you put a ‘hinge’ object, the door will pivot around the hinge; when you put a ‘panel’ object the door will pivot around the ‘side’ of the ‘panel’. When the door object in Sweethome3d has a hinge it is always preferable to use it, it is more intuitive and the door pivot as in real life.
It is also good to group together all the moving part of the door as you did, otherwise only the object_id will pivot (ex: if you have a handle, and you only put the panel in the object_id, the handle will not pivot with the door).

In your case:

- entity: input_boolean.floorplan_test
    type3d: door
    object_id: <drd>    <-----good
    action: default
    door:
      doortype: slide
------
      side: right
      panel: <panel object id>
------
or
------
      hinge: <hinge object id>
------
      percentage: '50'
      direction: .....

Were you able to fix your problem ?

I haven’t been working on it to much lately. I will update after I’m back at it.

1 Like

Hi, I had issues that some of my textures would not be loaded in HA. When I open the obj file in Xcode or on a Windows PC it would show everything just fine.

I found what the issue was … “Dont export the obj file with an underscore in the name!”

Hopefully this can help some other users from the hassle that I had to go trough :smiley:

Stopped working for me on update to 2023.4
Is that true for anyone else? I just get a blank page instead of loading my model.

1 Like

Hi FortranFour,
I have encountered the same problem

2 Likes

Floor3D doesn’t even work from my SmartPhone (iPhone)
Any suggest?

2 Likes

Hello all i will look into it during the week end

1 Like

Please test the 1.5.2 in 2023.4 and tell me if it is working. Thanks

1 Like

Yes, working again. Thank you!