Dymamic Icons for Ranged values

Not sure if this is already implemented but I have noticed some logic misrepresentation of icons where a range is specified (such as thermostat settings).

I’ll explain what I mean, say you have a thermostat ‘setpoint’ in your sitemap, defined with a range of 5 to 30 degrees, this gives us an actual range of 26 degrees, but the icon will only ever show the icon based on the physical setting (the temperature). In order to show any item of this type as fully on (the icon, i mean) it would have to have a level of 100 degrees (maybe if my house is on fire?).

Can we not show the icon as fully on (maxed out) when the temp is at its maximum setting (based on the range). This would give a far more pleasing visual representation of the state of the level.

Read the dynamic icons section.

I guess it should work if you create your own icons set (just copy and rename the ones you want to customize), then name the icons (the part behind the dash is the important one) accordingly, for example the *-100 becomes *-30.


Sure, we could all do that, it’s a workaround, but it’s also just as easy to change the formula that picks the icon at the root level (it already has to pick the icon, after all).

"iconname-" & str((status / max) * 100)

Would give a basic representation, or:

"iconname-" & str((status / (max-min)) * 100)

Would give a representation of the range itself.

Just my 2-cents.

1 Like

It’s not a workaround. It is how it is designed, implemented, and intended to work.

There is nowhere in the sitemap nor the items definitions to “change the formula”.

But if you have a way to implement something like that I’m sure the maintainers would welcome the PR.


Got a scenario where I want to have dynamic icons for the rpms on my pool pump. I decided to just copy from the classic icons and rename them as follows thinking this would work.


So it turns out that item hits the numbers 100, 200, and 300, I am able to get it to work but if it’s anywhere in between it chooses the default value. Is there a way to have it display correctly even if its in ranges? For instance if it is 150 I should see the icon for 100, 225 should show the 200, and so on.
Can I do this without having 300 icons, that would be insane. @psych Idea above makes sense but as @rlkoshak mentioned there is no way to do that. Is there maybe a way to use one value for the icon and another for what is displayed as the value? If so I would be able to create a calculation for the icon and then just pass the real rpm value to be displayed on the sitemap.

Found this bug report/enhancement request for the same issue. https://github.com/eclipse-archived/smarthome/issues/4494 but would appreciate any thought on how to workaround if possible.

The solution is already described. Create a custom icon set to suit your circumstances.

300 + icons? I did create custom icons but they won’t display values in between.

No - you can at most have a hundred or so in any icon family.
But aren’t you trying to have less?

They can and do. Share what you tried.

Example icon family for a Number Item

You must have the default image or it just doesn’t work.
If the Number has value NULL, 0 , 5.213, or -4 then thermo is shown
If the Number has value 10 or 19.99, then thermo-10 is shown
If the Number has value 31 or 77.9 or 100, then thermo-30 is shown
If the Number has value 101 or 678.2, then thermo is shown. I’d prefer if it showed thermo-30 but it doesn’t - 100+ is considered out of range and so defaults.
The picker deals with decimal states, but you can only have “integer” icons.

Yes Idealy I would like to have as few icons as possible. When the values is less than 100 it works. Those work without a hitch but in my case all my values will always be over 100 so it always shows my default icon or thermo.svg in your case. From all I have read, it seems that anything over 100 won’t work so I am looking for a workaround for that particular case.

You can use this technique.
Have a scaled Item version of your number, in the case of 0-300 you might divide-by-ten for sanity. You can do that with rule or perhaps transform depending on data source.
Then arrange an icon set as you wish for 0-30 values.
Display that Item in your sitemap or HABpanel, use a multiply-by-ten transformation in your state presentation format to restore the original value for viewing.

oh great I’ll check that out thank you! looks like that would solve it!

@rossko57 thanks for pointing that out. I was able to get it to work. It’s a little confusing but I was able to use the Proxy Item Design Pattern along with your hints to get this going. Here is how I got it working in case anyone runs into this in the future.

Icons required I used the same as the heating icons for my test but you would replace these with the icons of your choice. I found the icons here.



    Number PentairIntellifloPump_RPM_PROXY "Pentair Pool Pump RPM" <rpm> // NO Binding, this is used for sitemap as a proxy switch using Design Pattern: Proxy Item
    Number PentairIntellifloPump_RPM_SEND "Pentair Pool Pump RPM" (gPentair) {channel="pentair:intelliflo:1:pump1:rpm"}  // send commands to pool pump
    Number PentairIntellifloPump_RPM_RECEIVE "Pentair Pool Pump RPM" (gPentair) {channel="pentair:intelliflo:1:pump1:rpm"}  // receive state updates from pool pump


    rule "Update Pentair Pool Pump RPM on receive command of Proxy Switch"
         Item PentairIntellifloPump_RPM_PROXY received command
          if(PentairIntellifloPump_RPM_SEND.state != receivedCommand) {        
             PentairIntellifloPump_RPM_SEND.sendCommand((( receivedCommand as Number * 3450 ) / 100).intValue)
             logInfo("pool.rules", "Pump Proxy received RPM command: " + ((( receivedCommand as Number * 3450 ) / 100).intValue))

    rule "Update Pentair Pool Pump RPM received update"
        Item PentairIntellifloPump_RPM_RECEIVE received update 
        if(PentairIntellifloPump_RPM_PROXY.state != PentairIntellifloPump_RPM_RECEIVE.state) {        
            PentairIntellifloPump_RPM_PROXY.postUpdate(((PentairIntellifloPump_RPM_RECEIVE.state as DecimalType / 3450) * 100).intValue)
            logInfo("pool.rules", "Pump RPM SCALED: " + ((PentairIntellifloPump_RPM_RECEIVE.state as Number / 3450) * 100).intValue)

Javascript Transform must be enabled

put this file inside Transform folder


//Scale up RPM to values between 0 and 3450 which is the range of the pentair pump
function scale(rpm) {
scaledrpm = (rpm * 3450) / 100 ;
return scaledrpm.toFixed(0);


Setpoint item=PentairIntellifloPump_RPM_PROXY label="RPM: [JS(scalerpmup.js):%s]" minValue=0 maxValue=100 step=1

Wow that was a lot of work for such a simple thing…

Here is what the sitemap looks like as the values ramp up from 0-100 (for dynamic icon) / 0-3450 (for visual).






1 Like

I think you could simplify your SEND and RECIEVE Items into one; they are after all linked to the same channel.
Disabling autoupdate on these Items would probably be helpful, to uncouple states from commands.

It took me a while to wrap my head around it. Initially, I had tried something like that but I got myself into an infinite loop and this way seemed to work rather well. When I get brave, I will take another look and see if I can simplify.

Hello together!

I have the same problem like Hector G - I want to display dynamic icons in a range from 950 to 1050. Glad to find the solution here which I consider of being a solution for my prolbem also, BUT: I don’t use sitemaps with openHAB. I’m using HABpanel exclusively as my frontend - and I cannot find a way to implement the above Javascript transformation while displaying an Item in a Dummy Widget.

Is there any solution for that using HABpanel?

You have to put the transformation on the Item state description, so that the transformation is done at the host. Then have your HABpanel widget use the transformed state, not the raw state. That part seems to give people trouble, but I have no experience to share there.