Hello Termplate Guru’s,
I’ve recieved some help from the community for this project before, now I’m looking to build a new feature requested by the community.
I’m sure if I spent a couple of days on it I’d figure it out, but maybe we can shortcut that a bit with help from someone that sees curly braces in their sleep.
I have a function in my custom macro
GitHub - SirGoodenough/Color-Multi-Tool: Toolbox to work with and convert colors rgb, hs, xy, and Color Name. It will also provide random colors in any format, attempt to match your RGB value to an official color, and test if the color is valid (numbers or name). (The name map is in the download for this, avail thru HACS as well)
That accepts an rgb color code and returns the HA color name for it. It also accepts a range so you don’t have to guess exact match. This means if you ask rgb2name([100,100,100],5) it will return a list of the color names in HA that range from [95,95,95] to [105,105,105] and all with numbers within that range.
That all works.
The request is to return the one color closest, which would be a more useful function indeed.
I was thinking of adding a bool to the option list and have it do this. That works and I got that.
I am also thinking of having 2 sections in the jinja and re-use some of ths code with yaml anchors to shorten it up. Done that before so I have that as well.
My problem is trying to envision the process. Maybe iterating the search with progressively larger range, then as soon as something is in the list, grab the first one and return it? That whole looping stuff in jinja gets me every time… Maybe there’s a better way as well. I’m not sure.
Maybe this could be the closest brighter color or the closest darker color, not sure. Returning 1 close color would be the goal and more useful that what I came up with originally.
Here’s the current code.
Thanks so much for reading this over.
I hope I provided a fun Sunday Afternoon puzzle for someone. Loops make me loopy…
{% macro rgb2name(_range, rgbl) %}
{#-
This template will accept a list representing an RGB value plus a range
value representing the window size of the 'close enough' color name.
It will return the Home Assistant Color name that matches it or is close
to it within a +/- range you specify.
> If you want only an exact match, then set the range to 0.
> If you think that +10/-10 is close enough, then set the range to 10.
For default the color is set to black [0,0,0] and the range is 0, so it will
by give you black for invalid input.
SAMPLE USAGE:
{% from 'color_multi_tool.jinja' import rgb2name %}
{{ rgb2name(10,rgbl) }}
REMEMBER:
Everything returned from a macro template is a string.
#### 🗿License Notice:
* I & my license require attribution as a link back to the original should
you use this code in your own creation.
* Here is a link to my license & the original github post
https://github.com/SirGoodenough/Color-Multi-Tool?tab=License-1-ov-file
expected to be followed & referenced
as attribution should you use this code elsewhere.
#}
{#- First a test to make sure input is valid #}
{%- if chkRGB(rgbl) | default(false) | bool %}
{#- Set defaults #}
{%- set out = ["black"] | list %}
{#- Pull in the data #}
{%- set _rnge = _range | default(0) | round(0,0) %}
{%- set iR = rgbl[0] | default(0) | int(0) %}
{%- set iG = rgbl[1] | default(0) | int(0) %}
{%- set iB = rgbl[2] | default(0) | int(0) %}
{#- Define Ranges for each color #}
{%- set _Rl = rgbl[0] + _rnge %}
{%- set _Gl = rgbl[1] + _rnge %}
{%- set _Bl = rgbl[2] + _rnge %}
{%- set _Rg = rgbl[0] - _rnge %}
{%- set _Gg = rgbl[1] - _rnge %}
{%- set _Bg = rgbl[2] - _rnge %}
{#- Grab matching colors out of the list. #}
{%- set out = _nameMap['_rgb'] |
selectattr('r', 'ge', _Rg) |
selectattr('r', 'le', _Rl) |
selectattr('g', 'ge', _Gg) |
selectattr('g', 'le', _Gl) |
selectattr('b', 'ge', _Bg) |
selectattr('b', 'le', _Bl) |
map(attribute='color') | list | default(['black']) %}
{{- out -}}
{%- else %}
{#- Input was not valid #}
{{-['black'] | list -}}
{%- endif %}
{% endmacro %}