Closed Zerogiven closed 3 weeks ago
One thing to say that the base image of the lights is with a red lighting
Hey,
I'd need to try this out to see if/how it works but forcing the red color on the required lights in SH3D sounds awkward. Maybe if the plugin can change them automatically to a red tint somehow. In any case, it sounds like this could only work in the "room overlay" mode.
Hmm ok, i understand :) the red light is, i think, cause doesn't shine as brightly as others(also not as far..) or maybe the filter hue-rotate works better with red ^^
But yeah, maybe only for room overlay mode possible, but i will try some configs getting for all modes done :)
however, this is a very very cool feature i think :D
Just want to let you know that i've got this easily working with the CSS output (only at the moment) :) This is my yaml (not exactly what yours produced but maybe you like it too :))
The only thing i've had to do was to render all RGBW Lights two times, once with a red light and once with a white light (ok don't ask me why the red thing is important, however i did not try others at the moment)
type: picture-elements
image: /local/plan/night.png
elements:
- type: custom:config-template-card
variables:
LIGHT_STATE: states['light.wohnzimmer_licht_couch'].state
COLOR_MODE: states['light.wohnzimmer_licht_couch'].attributes.color_mode
LIGHT_COLOR: states['light.wohnzimmer_licht_couch'].attributes.hs_color
BRIGHTNESS: states['light.wohnzimmer_licht_couch'].attributes.brightness
entities:
- light.wohnzimmer_licht_couch
element:
type: image
image: /local/plan/transparent.png
state_image:
'on': >-
${COLOR_MODE === 'color_temp' ?
'/local/plan/light.wohnzimmer_licht_couch.png' :
'/local/plan/light.wohnzimmer_licht_couch_red.png' }
entity: light.wohnzimmer_licht_couch
style:
filter: '${ "hue-rotate(" + (LIGHT_COLOR ? LIGHT_COLOR[0] : 0) + "deg)"}'
opacity: '${LIGHT_STATE === ''on'' ? (BRIGHTNESS / 254) : ''100''}'
mix-blend-mode: lighten
pointer-events: none
left: 50%
top: 50%
width: 100%
- type: state-icon
entity: light.wohnzimmer_licht_couch
title: null
style:
top: 79.31%
left: 36.85%
border-radius: 50%
text-align: center
background-color: rgba(255, 255, 255, 0.3)
tap_action:
action: toggle
This was my firs tryout so, nothing optimized but it works and looks very cool if using RGBW or CCT lights and a bit more "realistic" :smiley:
I shortened my code, i also made some conditional things to get a morning/day/evening/night rendering
Oh i forgot two things... i rendered the light graphics with a different time than the "night.png"
night.png = 20:30 lights = 01:00
The "trick" is mix-blend-mode: lighten
and a transparent 1x1 pixel png which is used when the light is off. So you can use a daylight rendering and see the RGB(W) effect too :)
And for CCT lamps :) (with white light rendering, red is only for RGB needed)
type: picture-elements
image: /local/plan/night.png
elements:
- type: custom:config-template-card
variables:
LIGHT_STATE: states['light.wohnzimmer_licht_couch'].state
LIGHT_COLOR: states['light.wohnzimmer_licht_couch'].attributes.hs_color
BRIGHTNESS: states['light.wohnzimmer_licht_couch'].attributes.brightness
entities:
- light.wohnzimmer_licht_couch
element:
type: image
image: /local/plan/transparent.png
state_image:
'on': '/local/plan/light.wohnzimmer_licht_couch.png'
entity: light.wohnzimmer_licht_couch
style:
filter: '${ "hue-rotate(" + (LIGHT_COLOR ? LIGHT_COLOR[0] : 0) + "deg)"}'
opacity: '${LIGHT_STATE === ''on'' ? (BRIGHTNESS / 254) : ''100''}'
mix-blend-mode: lighten
pointer-events: none
left: 50%
top: 50%
width: 100%
- type: state-icon
entity: light.wohnzimmer_licht_couch
title: null
style:
top: 79.31%
left: 36.85%
border-radius: 50%
text-align: center
background-color: rgba(255, 255, 255, 0.3)
tap_action:
action: toggle
Let's see if I understand all of this...
Assuming we want to use the CSS lighten mode, which I think is a good approach, the only way I can get away with applying a hue-rotate only where the light illuminates the furniture is if the rest of the floor plan is either transparent or totally black. Is that the case with your red light overlay image?
I didn't see a way to change, in SH3D, the light color. Did you just create a red light source from the get-go or do you have some way to change an existing light's color? While I'd prefer to have some way to change the light color before rendering, I'm also OK with documenting that RGB lights need to be red when designing the floor plan in SH3D.
As for why it needs to be red, I'm guessing that's just the assumption of the hue-rotate degrees. Maybe we can add some offset to the calculated degrees to make it work with a white base color but I'm not entirely sure that's how hue works in the first place since, I think, a white light is represented with brightness alone anyway.
I am wondering, though, how the CSS lighten mix-mode will work if I have a base image that's not pitch black, i.e., the floorplan is somewhat illuminated by the sun, with a colored light on it and the brightness level of both lights is similar. Some pixels might be taken from the base image while others from the colored light and I'm wondering how it'll look. If it looks OK, then I might just end up making all of the overlay images in black (set the time to midnight and disable ceiling lights).
Regarding the CCT lights, do they really need to be handled differently? Can't I use the same YAML as RGB with a default color or something? I don't have any in my HA so I'm not sure how they're represented.
I'd also appreciate it if you could share samples of the images in your floorplan to along with the YAML you posted so I can better understand what kind of images I need to prepare
Hi!
First of all, great project, thanks for all the work! Tried to implement Zerogiven's code and it was easier than expected. Used GIMP to subtract the difference for each lamp ON image from the base.png and added transparency to them with an alpha channel. Also created a red version from these transparent images with the Colorize function. With the help of ChatGPT I was able to create a GIMP pythonfu script that works ok, although needs some work for sure. :D
Here's an example of the transparent and red images:
The GIMP script: (has to be placed in
from gimpfu import *
import os
def subtract_images_in_folder(base_image_path, folder_path):
# Load the base image
base_image = pdb.gimp_file_load(base_image_path, base_image_path)
base_layer = pdb.gimp_image_get_active_layer(base_image)
# Ensure the base image has an alpha channel
if not pdb.gimp_drawable_has_alpha(base_layer):
pdb.gimp_layer_add_alpha(base_layer)
# List all files in the folder
for filename in os.listdir(folder_path):
if filename.endswith(".png") and filename != "base.png":
image_path = os.path.join(folder_path, filename)
# Load the current image
current_image = pdb.gimp_file_load(image_path, image_path)
current_layer = pdb.gimp_image_get_active_layer(current_image)
# Duplicate the base layer into the current image
base_copy = pdb.gimp_layer_new_from_drawable(base_layer, current_image)
pdb.gimp_image_insert_layer(current_image, base_copy, None, 0)
# Set the blending mode to 'Difference' for subtraction
pdb.gimp_layer_set_mode(base_copy, DIFFERENCE_MODE)
# Merge the layers to apply the difference
merged_layer = pdb.gimp_image_merge_down(current_image, base_copy, CLIP_TO_BOTTOM_LAYER)
# Select the black color to make it transparent
pdb.gimp_image_select_color(current_image, CHANNEL_OP_REPLACE, merged_layer, (0, 0, 0))
pdb.gimp_edit_clear(merged_layer)
pdb.gimp_selection_none(current_image)
# Save the result with the "_subtracted" suffix
output_path = os.path.join(folder_path, filename.replace(".png", "_subtracted.png"))
pdb.file_png_save_defaults(current_image, merged_layer, output_path, output_path)
# Create a red version by colorizing
red_layer = pdb.gimp_image_get_active_layer(current_image)
# Apply the colorize effect (Hue: 1, Saturation: 0.75, Lightness: 0)
pdb.gimp_colorize(red_layer, 360, 75, 0)
# Save the red version with '_red' suffix
output_red_path = os.path.join(folder_path, filename.replace(".png", "_red.png"))
pdb.file_png_save_defaults(current_image, red_layer, output_red_path, output_red_path)
# Clean up
pdb.gimp_image_delete(current_image)
# Clean up the base image
pdb.gimp_image_delete(base_image)
register(
"python_fu_subtract_images_in_folder",
"Subtract multiple images from a base image in a folder and create transparent results",
"Subtract all PNG images in a folder from a base image and output the subtracted images.",
"Your Name", "Your Name", "2024",
"<Toolbox>/Python-Fu/Subtract Images from Folder...",
"",
[
(PF_FILE, "base_image_path", "Path to the base image (base.png)", ""),
(PF_DIRNAME, "folder_path", "Path to the folder containing the images", ""),
],
[],
subtract_images_in_folder)
main()
Card:
type: picture-elements
image: /local/HA_Floorplan_0.6/base.png
elements:
- type: custom:config-template-card
variables:
LIGHT_STATE: states['light.<entity>'].state
COLOR_MODE: states['light.<entity>'].attributes.color_mode
LIGHT_COLOR: states['light.<entity>'].attributes.hs_color
BRIGHTNESS: states['light.<entity>'].attributes.brightness
entities:
- light.<entity>
element:
type: image
image: /local/transparent.png
state_image:
'on': >-
${COLOR_MODE === 'color_temp' ?
'/local/HA_Floorplan_0.6/light.<entity>.png' :
'/local/HA_Floorplan_0.6/light.<entity>_red.png' }
entity: light.<entity>
style:
filter: '${ "hue-rotate(" + (LIGHT_COLOR ? LIGHT_COLOR[0] : 0) + "deg)"}'
opacity: '${LIGHT_STATE === ''on'' ? (BRIGHTNESS / 255) : ''100''}'
mix-blend-mode: lighten
pointer-events: none
left: 50%
top: 50%
width: 100%
.
.
.
End result:
Used transparent light sources as 'ceilings' for each room with 0.5 percent power to avoid having completely black rooms with night renders (thanks for the always on feature!).
Hope this helps!
This is very interesting, thanks! So, from what I understand, the plugin needs to implement the following:
I don't see, though, how this could be done with room-overlay nor complete renders though. For room-overlay we'll have images with all the light combinations in the same room so I can't colorize all of them in red. I'm not sure how popular the complete renders mode is to begin with so we can ignore it for now. We will need to, at least, add a warning or something when any light is configured for RGB and the mode isn't CSS overlay.
If anyone can provide a link or something to the required algorithms for finding the differences and colorize an image, I can try to implement something like this.
Hey, while I couldn't use the GIMP script directly, the documentation for the colorizing function was enough for me to understand how to tint the overlay image :) I have a pull request ready but, before I merge it, anyone care to try it out: https://github.com/shmuelzon/home-assistant-floor-plan/actions/runs/10798997216/artifacts/1916013143
The only issue I'm aware of right now (and I guess it's the same when done manually as above) is when selecting an RGB light that's close to white/any shade of gray, the image is still red-tinted because the hue of grays is 0 (along with 0 saturation), so we don't change the hue of the tinted image keeping it as white. The YAML does support RGBW lights and then the "regular" image is used as a base and only brightness affects it but I think it'll still be red-ish when in RGB mode.
I still want/need to improve the generation of the overlay image, any ideas there are welcome!
Great, thanks for the build. One thing you could add is saturation through opacity ( :D ). Hear me out pls:
In my tests it works rather ok and doesn't show the bugs with saturation mentioned on other sites and also works like a charm with temp-only settings (Kelvin-based, only warm-cold, no RGB/HSL)
Here's a sample of my config that works fairly OK with saturation:
type: picture-elements
image: /local/floorplan/base.png?version=0CDE5A95DAC7881B7EDEA89880558DE9
elements:
- type: custom:config-template-card
variables:
LIGHT_STATE: states['light.top_left'].state
BRIGHTNESS: states['light.top_left'].attributes.brightness
entities:
- light.top_left
element:
type: image
image: >-
/local/floorplan/transparent.png?version=56ABE4CBC175363DA0810882244B34FF
state_image:
'on': >-
/local/floorplan/light.top_left.png?version=6C03BB36204335FFE67E68B1D8328664
entity: light.top_left
style:
opacity: '${LIGHT_STATE === ''on'' ? (BRIGHTNESS / 255) : ''100''}'
pointer-events: none
left: 50%
top: 50%
width: 100%
- type: custom:config-template-card
variables:
LIGHT_COLOR: states['light.top_left'].attributes.hs_color
entities:
- light.top_left
element:
type: image
image: >-
/local/floorplan/transparent.png?version=56ABE4CBC175363DA0810882244B34FF
state_image:
'on': '/local/floorplan/light.top_left.red.png?version=AFA91B481FB27E832407893D6A55FA60'
entity: light.top_left
style:
filter: '${ "hue-rotate(" + (LIGHT_COLOR ? LIGHT_COLOR[0] : 0) + "deg)"}'
opacity: '${ (LIGHT_COLOR ? LIGHT_COLOR[1] : 100) + ''%''}'
pointer-events: none
left: 50%
top: 50%
width: 100%
Since I understand very little of the HSV colorspace, can you please explain why this is better and, perhaps, add screenshots to compare the two YAMLs' results?
It's problematic... I am testing with 5 rgb lights in one room and overlapping layers isn't going too well... I will look through the backups as I did a similar setup 2 years ago though there was almost no overlapping of layers...
Coming from a photography background I honestly miss Photoshop blending precision on layers TBH :)
I'll post my findings in a few days
Since I understand very little of the HSV colorspace, can you please explain why this is better and, perhaps, add screenshots to compare the two YAMLs' results?
In theory there are a few things to consider:
Now, these concepts in bitmaps are seen as:
The normal approach to coloring or recoloring a bitmap is to handle the luminosity and color separately. A base dark layer + a luminosity layer + a color layer The luminosity layer controls brightness through opacity The color layer controls color through opacity and hue-rotation
These layers should have some blending modes set (lighten for luminosity layer and color for the color layer)
The problem appears when you overlap multiple such layers and colors start to blend erratically... https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode - this helps with blending modes - as a reference
Ok, played a little and here's what I came up with... this is the best thing I could do with the given images generated by the tool:
What I still need to do for a better looking layout:
Here is how it renders:
Here is the configuration:
- type: picture-elements
image: /local/floorplan/base.png
elements:
#LIVING LIGHTS
- type: custom:config-template-card
variables:
LIGHT_STATE: states['light.top_light'].state
BRIGHTNESS: states['light.top_light'].attributes.brightness
entities:
- light.top_light
element:
type: image
image: /local/floorplan/transparent.png
state_image:
'on': /local/floorplan/light.top_light.png
entity: light.top_light
style:
opacity: '${LIGHT_STATE === "on" ? (BRIGHTNESS / 255) : "0"}'
mix-blend-mode: lighten
pointer-events: none
left: 50%
top: 50%
width: 100%
- type: custom:config-template-card
variables:
LIGHT_STATE: states['light.table_light'].state
BRIGHTNESS: states['light.table_light'].attributes.brightness
entities:
- light.table_light
element:
type: image
image: /local/floorplan/transparent.png
state_image:
'on': /local/floorplan/light.table_light.png
entity: light.table_light
style:
opacity: '${LIGHT_STATE === "on" ? (BRIGHTNESS / 255) : "0"}'
mix-blend-mode: lighten
pointer-events: none
left: 50%
top: 50%
width: 100%
- type: custom:config-template-card
variables:
LIGHT_STATE: states['light.strip'].state
BRIGHTNESS: states['light.strip'].attributes.brightness
entities:
- light.strip
element:
type: image
image: /local/floorplan/transparent.png
state_image:
'on': /local/floorplan/light.strip.png
entity: light.strip
style:
opacity: '${LIGHT_STATE === "on" ? (BRIGHTNESS / 255) : "0"}'
mix-blend-mode: lighten
pointer-events: none
left: 50%
top: 50%
width: 100%
- type: custom:config-template-card
variables:
LIGHT_STATE: states['light.top_lamp'].state
BRIGHTNESS: states['light.top_lamp'].attributes.brightness
entities:
- light.top_lamp
element:
type: image
image: /local/floorplan/transparent.png
state_image:
'on': /local/floorplan/light.top_lamp.png
entity: light.top_lamp
style:
opacity: '${LIGHT_STATE === "on" ? (BRIGHTNESS / 255) : "0"}'
mix-blend-mode: lighten
pointer-events: none
left: 50%
top: 50%
width: 100%
- type: custom:config-template-card
variables:
LIGHT_STATE: states['light.top_left'].state
BRIGHTNESS: states['light.top_left'].attributes.brightness
entities:
- light.top_left
element:
type: image
image: /local/floorplan/transparent.png
state_image:
'on': /local/floorplan/light.top_left.png
entity: light.top_left
style:
opacity: '${LIGHT_STATE === "on" ? (BRIGHTNESS / 255) : "0"}'
mix-blend-mode: lighten
pointer-events: none
left: 50%
top: 50%
width: 100%
- type: custom:config-template-card
variables:
LIGHT_STATE: states['light.lamp'].state
BRIGHTNESS: states['light.lamp'].attributes.brightness
entities:
- light.lamp
element:
type: image
image: /local/floorplan/transparent.png
state_image:
'on': /local/floorplan/light.lamp.png
entity: light.lamp
style:
opacity: '${LIGHT_STATE === "on" ? (BRIGHTNESS / 255) : "0"}'
mix-blend-mode: lighten
pointer-events: none
left: 50%
top: 50%
width: 100%
#LIVING COLOR LIGHTS
- type: custom:config-template-card
variables:
LIGHT_STATE: states['light.table_light'].state
LIGHT_COLOR: states['light.table_light'].attributes.hs_color
BRIGHTNESS: states['light.table_light'].attributes.brightness
entities:
- light.table_light
element:
type: image
image: /local/floorplan/transparent.png
state_image:
'on': /local/floorplan/light.table_light.red.png
entity: light.table_light
style:
filter: >-
${ "saturate(" + (LIGHT_COLOR ? LIGHT_COLOR[1] : 100) + "%)
hue-rotate(" + (LIGHT_COLOR ? LIGHT_COLOR[0] : 0) + "deg)"}
opacity: '${LIGHT_STATE === "on" ? (BRIGHTNESS / 255) : "0"}'
mix-blend-mode: color
pointer-events: none
left: 50%
top: 50%
width: 100%
- type: custom:config-template-card
variables:
LIGHT_STATE: states['light.strip'].state
LIGHT_COLOR: states['light.strip'].attributes.hs_color
BRIGHTNESS: states['light.strip'].attributes.brightness
entities:
- light.strip
element:
type: image
image: /local/floorplan/transparent.png
state_image:
'on': /local/floorplan/light.strip.red.png
entity: light.strip
style:
filter: >-
${ "saturate(" + (LIGHT_COLOR ? LIGHT_COLOR[1] : 100) + "%)
hue-rotate(" + (LIGHT_COLOR ? LIGHT_COLOR[0] : 0) + "deg)"}
opacity: '${LIGHT_STATE === "on" ? (BRIGHTNESS / 255) : "0"}'
mix-blend-mode: color
pointer-events: none
left: 50%
top: 50%
width: 100%
- type: custom:config-template-card
variables:
LIGHT_STATE: states['light.top_lamp'].state
LIGHT_COLOR: states['light.top_lamp'].attributes.hs_color
BRIGHTNESS: states['light.top_lamp'].attributes.brightness
entities:
- light.top_lamp
element:
type: image
image: /local/floorplan/transparent.png
state_image:
'on': /local/floorplan/light.top_lamp.red.png
entity: light.top_lamp
style:
filter: >-
${ "saturate(" + (LIGHT_COLOR ? LIGHT_COLOR[1] : 100) + "%)
hue-rotate(" + (LIGHT_COLOR ? LIGHT_COLOR[0] : 0) + "deg)"}
opacity: '${LIGHT_STATE === "on" ? (BRIGHTNESS / 255) : "0"}'
mix-blend-mode: color
pointer-events: none
left: 50%
top: 50%
width: 100%
- type: custom:config-template-card
variables:
LIGHT_STATE: states['light.top_left'].state
LIGHT_COLOR: states['light.top_left'].attributes.hs_color
BRIGHTNESS: states['light.top_left'].attributes.brightness
entities:
- light.top_left
element:
type: image
image: /local/floorplan/transparent.png
state_image:
'on': /local/floorplan/light.top_left.red.png
entity: light.top_left
style:
filter: >-
${ "saturate(" + (LIGHT_COLOR ? LIGHT_COLOR[1] : 100) + "%)
hue-rotate(" + (LIGHT_COLOR ? LIGHT_COLOR[0] : 0) + "deg)"}
opacity: '${LIGHT_STATE === "on" ? (BRIGHTNESS / 255) : "0"}'
mix-blend-mode: color
pointer-events: none
left: 50%
top: 50%
width: 100%
- type: custom:config-template-card
variables:
LIGHT_STATE: states['light.lamp'].state
LIGHT_COLOR: states['light.lamp'].attributes.hs_color
BRIGHTNESS: states['light.lamp'].attributes.brightness
entities:
- light.lamp
element:
type: image
image: /local/floorplan/transparent.png
state_image:
'on': /local/floorplan/light.lamp.red.png
entity: light.lamp
style:
filter: >-
${ "saturate(" + (LIGHT_COLOR ? LIGHT_COLOR[1] : 100) + "%)
hue-rotate(" + (LIGHT_COLOR ? LIGHT_COLOR[0] : 0) + "deg)"}
opacity: '${LIGHT_STATE === "on" ? (BRIGHTNESS / 255) : "0"}'
mix-blend-mode: color
pointer-events: none
left: 50%
top: 50%
width: 100%
Hmmm one idea, when you do the masking of the red images you have a hard pass, meaning that what falls below the threshold you cut the image suddenly.
Light has falloff, what if you could add a shaded transparency ? You apply on top of the cut image a radius based transparency gradient. That would get rid of the hard differences when overlaying multiple lights. I'll try something and get back to you.
LE: this solves the falloff problem from the picture-elements directly: mask-image: radial-gradient(farthest-side at 10% 10%, rgba(0,0,0,1) 40%,transparent 70%) I highly recommend this to make things look more natural play around with percentages per each light
updated render (with added radial-gradient
@andyxpert So, what you're suggesting is that for RGB lights, I add two YAML sections? The first, something like the following that handles on/off and brightness with blend mode lighten?
- type: custom:config-template-card
variables:
LIGHT_STATE: states['light.table_light'].state
BRIGHTNESS: states['light.table_light'].attributes.brightness
entities:
- light.table_light
element:
type: image
image: /local/floorplan/transparent.png
state_image:
'on': /local/floorplan/light.table_light.png
entity: light.table_light
style:
opacity: '${LIGHT_STATE === "on" ? (BRIGHTNESS / 255) : "0"}'
mix-blend-mode: lighten
pointer-events: none
left: 50%
top: 50%
width: 100%
Then, at the end of all the "regular" lights and the above for RGB lights, I add another YAML section to handle the color of the RGB lights, like so:
- type: custom:config-template-card
variables:
LIGHT_STATE: states['light.table_light'].state
LIGHT_COLOR: states['light.table_light'].attributes.hs_color
BRIGHTNESS: states['light.table_light'].attributes.brightness
entities:
- light.table_light
element:
type: image
image: /local/floorplan/transparent.png
state_image:
'on': /local/floorplan/light.table_light.red.png
entity: light.table_light
style:
filter: >-
${ "saturate(" + (LIGHT_COLOR ? LIGHT_COLOR[1] : 100) + "%)
hue-rotate(" + (LIGHT_COLOR ? LIGHT_COLOR[0] : 0) + "deg)"}
opacity: '${LIGHT_STATE === "on" ? (BRIGHTNESS / 255) : "0"}'
mix-blend-mode: color
mask-image: radial-gradient(farthest-side at 10% 10%, rgba(0,0,0,1) 40%,transparent 70%)
pointer-events: none
left: 50%
top: 50%
width: 100%
Did I get it right?
I have another commit I have lined up that needs what I currently have for RGB as a prerequisite so I'm going to merge the current implementation. We can then take on improving it with the above or any other suggestion that could work.
Great, let's leave the color light implementation as is and I can open a new discussion on the improvement of color lights render.
The above suggestion is not perfect as an almost-white color would make the underlying layers render in grayscale... Still playing with the yaml in my spare time...
I think I managed to make it render correctly.
filter: >-
${ "opacity(" + (LIGHT_COLOR ? LIGHT_COLOR[1] : 100) + "%)
hue-rotate(" + (LIGHT_COLOR ? LIGHT_COLOR[0] : 0) + "deg)"}
opacity: '${LIGHT_STATE === "on" ? (BRIGHTNESS / 255) : "0"}'
mix-blend-mode: normal
blend mode set to normal for color lights, style opacity set to light brightness and filter opacity set to light saturation. this fixes the saturation-going-gray issue mentioned above.
I'll start a discussion with a proper explanation and examples, screenshots and maybe that will be a starting point for how you aggregate the yaml file. Maybe you could add it as a toggle in the plugin (color lights V1/V2) so both yaml styles are available for people to choose which they prefer.
I'll start a discussion with a proper explanation and examples, screenshots and maybe that will be a starting point for how you aggregate the yaml file.
That would be great, thanks!
Maybe you could add it as a toggle in the plugin (color lights V1/V2) so both yaml styles are available for people to choose which they prefer.
I would rather just stick with one if it provides better results as more options raise more questions. I was actually considering also removing the option for different rendering modes for the same reason but, we'll see...
I'll start a discussion with a proper explanation and examples, screenshots and maybe that will be a starting point for how you aggregate the yaml file.
That would be great, thanks!
@shmuelzon Hi, since the discussions tab is not enabled, I'm writing here with the final config I have for the YAML to display color lights properly:
- type: custom:config-template-card
variables:
LIGHT_STATE: states['light.top_left'].state
BRIGHTNESS: states['light.top_left'].attributes.brightness
entities:
- light.top_left
element:
type: image
image: /local/floorplan/transparent.png
state_image:
'on': /local/floorplan/light.top_left.png
entity: light.top_left
style:
mask-image: >-
radial-gradient(farthest-side at 30% 70%, rgba(0,0,0,1) 20%,
transparent 40%)
opacity: '${LIGHT_STATE === "on" ? (BRIGHTNESS / 255)*0.8+0.2 : "0"}'
mix-blend-mode: lighten
pointer-events: none
left: 50%
top: 50%
width: 100%
- type: custom:config-template-card
variables:
LIGHT_STATE: states['light.top_left'].state
LIGHT_COLOR: states['light.top_left'].attributes.hs_color
BRIGHTNESS: states['light.top_left'].attributes.brightness
entities:
- light.top_left
element:
type: image
image: /local/floorplan/transparent.png
state_image:
'on': /local/floorplan/light.top_left.red.png
entity: light.top_left
style:
mask-image: >-
radial-gradient(farthest-side at 20% 70%, rgba(0,0,0,1)
20%,transparent 40%)
filter: >-
${ "opacity(" + (LIGHT_COLOR ? LIGHT_COLOR[1] : 100) + "%)
hue-rotate(" + (LIGHT_COLOR ? LIGHT_COLOR[0] : 0) + "deg)"}
opacity: '${LIGHT_STATE === "on" ? (BRIGHTNESS / 255)*0.8+0.2 : "0"}'
mix-blend-mode: normal
pointer-events: none
left: 50%
top: 50%
width: 100%
So, first I add the color light as a "lighten" layer to display the luminance layer (opacity style for brightness and "lighten" as blend mode). Then I added the same color light (after, so it's on top) as a "color" layer to display its color (opacity style for brightness, hue-rotate for color and blend mode set to normal - so it leaves the color intact) I also added a "mask-image" with radial-gradient for both of them to avoid spilling the light too far away (light follows an inverse-square rule and its intensity should fall-off fairly quickly - the percentages should be modified for each light based on how the lights are placed in the room/house layout... trial & error for each of them to show best results - these percentages could also be linked to light brightness so it spreads more when the light is brighter... )
For me this resulted in almost perfect light display, blend of light color and as far as I can see it's almost perfect so I'm pleased with the result.
You could alter how the YAML is generated to take into account the duplicated layers and add the brightness/color configs by default with the 2 blend modes. the radial-gradient in mask-image could be "commented" by default and each user can decide whether they want it or not per each light...
Hope this helps
@andyxpert thanks for that! A couple of question, if I may:
Hi,
the mask-image I used to add a falloff transparency for the cutouts Here for example I have a light that can bleed over 10m over the long hallway - adding the mask-image controls the layer transparency to avoid rendering the light layer on the right-far-side wall. Of course, sometimes we may want that, that's why I mentioned that the mask-image should be optional and only used by users if they want to on each light - for some it could help, while for others it may not be needed... depends on how SweetHome renders the cutout images
"lights close to white are displayed as red" indeed they are, as they should be, as they have a color component... but the method I proposed uses the saturation as an opacity filter rendering the light OK
Hi,
One last nice thing which would be very nice is to get RGB(W) renderings for defined lights. I saw this at this tutorial (in german...) https://smarthomebastler.at/floorplan-dashboard-neu-in-2022/
no idea if this could be a way here too :)