3D Room Lighting Dashboard With Dynamic Auto Scene Changes

I saw some posts in the HA subreddit where people are making 3D Dashboards using the free Sweet Home 3D model software. It got me interested if this could be done in Hubitat. I did find a way, all local to the hub. So I thought I would share what I did.

Now, the way they have been doing it with HA, is to make a 3D model of a room, and add all the lights in the right places. They then set time to 4pm, render an image with all lights off, and then one with all lights on. They then chop up the picture with editing software so each light gets its own section of the dashboard image as a separate image, and when lights go on and off, they use some integration to update that portion of the image on the dashboard to show the light in that area is on or off when it is switched. This can be done with Hubitat as well, if the grid gap is set to zero, and all the pieces can be seen as one image.

However, what I found was I have lights too close together to do that, as it would make for some confusing shading and lighting effects that don't make sense and it would really look bad. It also doesn't show ambient lighting from the sun in the windows for the correct time of day.

What I used instead is the nine scenes that I use, that change through the day, instead of basing it on individual lights. I have the scenes set so that it is pretty rare for me to ever adjust a light manually, so chopping it all up by light areas to show individual lights being turned on and off isn't something I need. All I want is for the lights to be accurate to the scene, and also for the time of day to be accurate to when the scene runs normally. You could do it the HA way and chop it all up, and still use the update method described below to update all the individual tiles based on device status changes, instead up just updating the whole dashboard image as a scene.

So, I rendered my room in Sweet Home 3D, as the base image. I then turned on the lights to the levels they use in each scene, and for the time of day of the scenes, and rendered an image for each one. I also rendered an image of each scene with all lights off, but with the correct time of day set for each scene.

Now, when my scenes change, the dashboard background changes to the correct image for the scene with lights on or off at correct dim levels, and it uses the proper background image based on if the scene is on or off from the presence sensor.

In Dashboards, you cannot auto refresh Backgrounds or Tile Backgrounds. What you can refresh is an Image tile (refresh is a setting for the tile). So, you have to use an Image tile as your dynamic background. This can be done by making one large tile for the image, and setting the z-index with CSS to a negative value so all other tiles will lay on top of it.

Use the tile ID of your image tile:

/* Make Image as background */
#tile-114 {
z-index: -10 !important;
}

I created a dashboard with column and row widths of 20. This creates quite a big grid for the dashboard, but it will give you more precise tile placements for where you want tiles on the image, and allow for different sized tiles depending how much you expand them. Create the background image tile first, and expand it to cover the whole area of your dashboard. Set the CSS z-index for the tile number. You can leave the image Url blank for now.

Now use Sweet Home software to build your room in 3D. When rendering (save photo), you can choose the time of day. Also go into the compass settings to set North based on how your room is positioned, so the sun will come in at the right angles. Choose the time of day for the scene, and render each scene with lights off.

Then, based on the dim levels and what lights are on for each scene, turn on the lights in Sweet 3D to match your scene, and render it again with the lights on at the same time of day as each scene's lights off image. Be sure to save a Sweet Home 3D file for each scene, so you can load it again to go back and change things if needed without having to set up each light again.

There is a checkbox for overhead lights on the render page. I don't see where it does much and I did not use it. I added overhead lights with a light source, and set elevation to be 8 feet. I added eight lights since I have recessed lights spread out over the room. They are not visible on the 3D room image. Note that the lighting is only applied with rendering, so you will not see the lights come on until it is rendered. Use one step down on quality to check how it look, then render in full quality and save.

When rendering the files, give them a name that includes the room name and the scene name, and if the scene is on or off. So something like KitchenMorningOn.png, KitchenDayOff.png, etc. You want a format for the files that lets you build the filename based on presence and scene.

Once you have all your files rendered, go to Settings -> File Manager and upload them all to the hub. Copy one of the files and name it what you want to use in the image tile, like room.png. Upload that file to the hub as well, and use it for the background image tile url.

To access the file, you need to use https://hub ip:8080/local/*room.*png in the image tile file path.

You should see the image now showing as the background. Now you can add all of your devices as tiles that are near the lights in the room. I went into Templates in the dashboard settings and made the "on" colors for the device types 1/2 transparent using the slider for custom template color.

Now you have a dashboard with a static image, but you want it to be dynamic to the scene and time of day.

For this, I used File Manager Driver. You can copy the code into the driver code, or use HPM to get it.

Once you have the driver installed, what you want to use is the Upload Image function:
Upload Image

You will use this function in an automation to change the background. It is changed by deciding what file you need based on the current conditions, and then building the filename so that you can copy that file over to the static file set in the image tile. I set this up in Webcore. Use the Webcore app settings page to include the File Manager Device in Webcore, as well as your presence/motion sensor.

In Webcore, make a piston that triggers with presence changing OR scene changing. Your scenes may be using Modes. When it triggers, one of those things has changed. Then build a filename based on the current values of room presence and scene.

If you have spaces in mode/scene names, you may want to strip them out for the filenames.
I strip out spaces from my scenes with:
stripspaces

Build a filename to match how you named you images. You might want to name your images so that you can use presence directly. Create a local variable in the Piston for fileName(String). Set filename by using Set Variable and an expression value,

I use "On" and "Off" based on active status. If active I make a filename with On, and if inactive I make a filename with Off. You could put active or inactive in the filename as well, or however you want to do it. It just needs to match how you named your files.

Then you want to copy that file over to a file named what you used for the filename in the image tile url. This is where you use File Manager Driver to do the copy from Webcore. I use a local variable to set Url first from the filename with an expression, then use that in the uploadImage command for File Manager Driver.

fileManager

Note that I am using an expression here again to build the Url that includes the file in the call to File Manager Device.

Once the file is copied, within the refresh time set in the image tile, it will change on the dashboard.

Lastly, here are a few of my dynamic scene images:





Good for some weekend where you have nothing better to do, as it takes some time to create the room in 3D, and time to generate the images and to add your devices to the dashboard.

11 Likes

Update:

I hurried the 3D renderings to get this working, but there are lots of furniture/texture packs that can be added to Sweet Home 3D for free. I also realized I had not created "rooms" which allows you to texture floors within each room. I also figured out how to add stairs by creating the basement, and I fixed the room dimensions to be more accurate. I suggest starting with real measurements for the room when creating it, I just dove in making walls.

For the actual background outside of the house, if you choose a color it still gets illuminated, so I went with one notch below full black at #020202, which become light gray for day renderings, and black for night renderings. You could also pick a grass texture, but it gets really bright during the day.

The re-rendering of everything was time consuming, but I'm more satisfied with the results. I also have a dashboard for my Home Theater room, so I made 3D dashboards for that room as well.

Also, being an image tile, clicking on it makes it full screen. If your image tile background is correctly sized to the dashboard size, clicking on the background makes your dashboard full screen, without any Hubitat icons on top of the page. Looks much better on a wall tablet.





6 Likes

A few thing to add regarding using an Image tile for a background.

  1. I had issues with the background showing through the edges if the image was not perfectly sized. You can make the background transparent with CSS to get rid of this.
  2. Sizing the image to fit the dashboard when rendering is tricky to get it just right. I found it is is easier to get it close, then tweak the dimensions with CSS.
  3. The image will not go fully to the left of the tile, but the image location within the tile can also be changed with CSS

So I use this in the CSS for the image tile now to take care of transparency and the z-index:

/* Make Image as background transparent and behind others */
#tile-114 {
z-index: -10 !important;
text-shadow:none;
background-color:transparent !important;
border:none;
}

I use this to change the image location and size (note that I am only using left position, width and height, but you can add right, top and bottom offsets if needed):

#tile-114.tile.image {
left: -10px !important;
width: 1320px !important;
height: 735px !important;
}

Check what your image size actually is, then make adjustments from there for width and height in CSS.

I am also playing with using an attribute tile instead of an image tile. It works about the same, but does not enlarge to full screen when clicked. This is a better method if you don't like the fact that an image background goes full screen when clicked.

I wrote this simple driver to save an image as an attribute. Use this instead of file manager to set one of the three image attributes to an image from local files. Just put in your hub ip address, then you just use only the file name to set the image. You can make as many attribute image virtual devices as you want. Just include that device in your dashboard, then choose it and use attribute type, and pick one of the three images from the attribute list. The nice thing about the attribute tiles is that they do not need to be refreshed, they instantly change when the image is changed.

Attribute Image.groovy

You need some different CSS to modify an attribute image, so use these below, in addition to the one to make it transparent is background like an image tile. You also want to get rid of the title on the attribute tile:

/* Image Resize Attribute */
#tile-32 .tile-primary .image {
left: -10px !important;
width: 1300px !important;
height: 650px !important;
}
#tile-32 .tile-title {
visibility: hidden;
white-space: nowrap !important;
overflow: unset;
}