openhab-core
openhab-core copied to clipboard
Item - Category field
The category-field on an item allow to set an icon for the item. Historically this field would only allow the "oh"-icons but now also accepts other libraries by prefixing the icon name with the library name and a ":". This is a great thing.
The problem however is that this new interpretation isn't carried over to the "list item widget". When setting a "default list item widget" the entire content of the "category"-field is copied and prefixed bij "oh:". Even when the orginal field already contains a library name. This results in the fact that the icon isn't valid anymore.
A solution to this problem might be to check for an ":" in the category-field. The "oh:" should only be prefixed if no ":"-character can be found.
@ghys Sounds like an UI issue. Can you take care of that?
Yep although we might need to redefine what an item's "category" means, both in core and in the UI. It was meant originally to convey both an icon and a semantic meaning, but now, this isn't so clear anymore.
See also #3173 which also shows that there is an issue with the differentiation between category and icon.
This come in recent 4.0 wishlist topic (forum is down atm, can't link it), so I'd consider it relevant for next release. Given that recent docs mention this section as icon, so my proposal is to relax validation of that field to match main UI syntax and also address that in icon lookups making i.e. <f7:battery>
request explicitly a battery icon from f7 iconset.
This issue has been mentioned on openHAB Community. There might be relevant details there:
https://community.openhab.org/t/openhab-4-0-wishlist/142388/393
I started to implement iconify support in BasicUI.
Here is the syntax I propose for category/icon: [<icon source>:[<icon set>:]]<icon name>
.
Icon source and icon set are optional. In case you set 2 segments, this is the icon source and the icon name.
Icon source can be either "oh", "if", "iconify", "f7", or "material". Default is "oh".
Icon set is by default "classic" if icon source is "oh" and it is empty for other icon sources.
MainUI will support all these icon sources. BasicUI will (after an enhancement) support all these icon sources except framework7.
Here are valid examples:
- temprature => OH icon from the classic iconset
- oh:temprature
- oh:classic:temperature
- if:mdi:home
- iconify:mdi:home
- f7:battery
- material:home
Is it ok for everybody ?
I think this is exactly the same syntax that was defined in MainUI for oh-icon. @ghys : please confirm.
Personally I have no objections to syntax itself, if it matches assumptions made earlier by UI does its. As a side note - UI does not ship image files but font files which means that use of them is generally speaking done through proper manipulation of CSS, will it work with other clients such as ios or android?
will it work with other clients such as ios or android?
These app will also have to be enhanced.
These app will also have to be enhanced.
Sorry, but this means that two more places will need extra logic around rendering these icons while they could be using iconset delivered by core. Making it so would allow to reduce logic in all clients and simply delegate work to IconServlet
.
If habpanel, mainui and basicui, android and ios have own iconsets and way to handle them then there is high likehood of running out of sync between all these places.
There is still an issue of item file parsed by core not being able to specify iconify using common syntax defined by mainui.
Sorry, but this means that two more places will need extra logic around rendering these icons while they could be using iconset delivered by core. Making it so would allow to reduce logic in all clients and simply delegate work to
IconServlet
. If habpanel, mainui and basicui, android and ios have own iconsets and way to handle them then there is high likehood of running out of sync between all these places.
The icon servlet implemented in core framework was designed to return an image (like PNG or SVG). Material-icons is in fact more a font than images and the API is JavaScript + CSS to be used directly in the HTML page (client side). Iconify also provides an API to be used in the HTML page using JavaScript + CSS. As iconify requires an internet access, doing that has also the advantage to have the browser caching the downloaded icons.
@ghys : please help me to explain why OH core icon provider/servlet is not adapted to these specific icon sources, in case I was not enough precise.
There is still an issue of item file parsed by core not being able to specify iconify using common syntax defined by mainui.
Isn't it what we are discussing here ?
The icon servlet implemented in core framework was designed to return an image (like PNG or SVG).
I had look at this and iconify has each icon in SVG format. The UI provider I linked in forum post embeds bunch of these svgs and make them available as svg. Its takin a lot of space hence I will look if its possible to tranform webfonts/fonts into svg on the fly to reduce size of binary distribution.
The framework7 icons and Material icons are available in SVG format resp. here and here, so they could be made into regular iconsets. If their size is a concern they could be distributed via the Marketplace, so users can install the bundle on-demand if they need them in BasicUI/sitemaps instead of being bundled in the distribution.
I think this is exactly the same syntax that was defined in MainUI for oh-icon. @ghys : please confirm.
I think framework7 and openhab aren't available, only f7 and oh (not a problem to have more), otherwise LGTM.
I think framework7 and openhab aren't available, only f7 and oh
I removed openhab and framework7.
they could be made into regular iconsets. If their size is a concern they could be distributed via the Marketplace, so users can install the bundle on-demand if they need them in BasicUI/sitemaps instead of being bundled in the distribution.
We have to consider that most users install OH on a RPI and the size is then critical. The option to have all these big libraries locally on the server looks relatively inappropriate especially when a user will only use few icons. For BasicUI at least, this is better to not rely on OH icon servlet and many local SVG files for iconify and material icons (material icons already included as font).
By the way, if someone wants to provide new OH iconsets, this will be also supported. I also made a change in BasicUI so that it can support any OH iconsets and not only the classic iconset.
We have to consider that most users install OH on a RPI and the size is then critical. The option to have all these big libraries locally on the server looks relatively inappropriate especially when a user will only use few icons. For BasicUI at least, this is better to not rely on OH icon servlet and many local SVG files for iconify and material icons (material icons already included as font).
I understand your concern, however some iconsets are already included in mainui. If they are are shifted in similar form/size to core then they can be safely removed from mainui, keeping net size of assembly the same. If you suggest that basicui will not ship fonts/icons themselves then you need to find a way to cross link basicui to rely on icons delivered from mainui or accept that they will be fetched each time by browser from internet.
If you suggest that basicui will not ship fonts/icons themselves then you need to find a way to cross link basicui to rely on icons delivered from mainui or accept that they will be fetched each time by browser from internet.
For iconify, yes I accept that the icons will be fetched by browser from internet. This will not be each time because the downloaded icons will then be cached by the browser. Usage of iconify is controlled by an option. If users don't want any internet access by UI, they can disable the option.
Google material font was already provided/packaged with BasicUI. So I have nothing to add (neither font nor SVG), I just allow users to use them.
By the way, as I previously said, if new OH iconsets are made available in the future through the OH icon servlet, they could also be used in any existing UI including BasicUI (small change was required for BasicUI and is now done in my PR).
I don't really like the idea of Basic UI doing requests to fetch icons from the internet for two reasons:
- Privacy
- It introduces yet another API. Since openHAB 2 we have an API endpoint to fetch the available icon sets: https://demo.openhab.org/rest/iconsets With this change in Basic UI every client needs to maintain a mapping of prefix to URL to fetch the icons. Why not add new icons as iconset and add a (global?) setting to select an iconset? A syntax like
if:mdi:home
could still be used to override the iconset selection for single icons.
This is only an option, disabled by default.
Defining other iconsets is another solution but the size of iconify library is not suitable with a small machine with not a lot of memory, like a RPI.
I like my option, no need to install any additional big iconset library in the server. Remember that the material design is always packaged with BasicUI.
And please note that MainUI does not rely on server iconset to render iconify icons too.
Defining other iconsets is another solution but the size of iconify library is not suitable with a small machine with not a lot of memory, like a RPI.
Are you concerned about memory as in RAM or as in persistent storage?
There's a binding that add several icon sets: https://community.openhab.org/t/iconify-icon-provider/144508 This binding downloads among other files this one which is ~3 MB large for a full icon set, so not too much I'd say.
And please note that MainUI does not rely on server iconset to render iconify icons too.
Something I don't like either, but that's a bit different. Basic UI renders Sitemaps, so people will soon create feature request for the iOS and Android app as well and then we have to implement it there as well.
This binding downloads among other files this one which is ~3 MB large for a full icon set, so not too much I'd say.
Provider you linked does use iconify json files as input at build time to createe individual svg files. The end result is a fat jar which is about 30 megs. However at runtime only small part of this amount is being kept in memory. During bootatrap provider scans files generated during build time and index them. Retrieval of icon is then very effective cause we know if icon is known, and its contents is simply streamed from jar, without storing it in memory or copying over disk. Its literally same as for webui.
30 megs for todays SD cards is not much. I agree its 1/4 of openHAB download size, however almost all of that are graphical resources. They will always cause increase of size. I think influxdb which sometimes gets deployed on raspberry takes much more disk space for work than this provider.
I had a look at generation of SVG from icon fonts (glyphs) and it is possible at certain effort. I have found code which can parse ttf font and generate valid svg font, however input files do not seem to have icon to character map. This seem to be an additional input. Anyhow, given the complexity of on-the-fly generation I think basic approach is still fine. ;)
I'll gladly accept a 30 megabytes increase if the items come all out of the box. It's basically nothing.
I tested how MainUI behaves with PR #3539, the new syntax is already partially supported.
classic:humidity is working:
OK
OK
OK
iconify:wi:day-sunny-overcast is partially working:
OK
KO
OK
if:wi:day-thunderstorm is partially working:
OK
KO
OK
oh:classic:pressure is not working:
material::favorite is not working but I am not sure if MainUI already supports Material icon source ? Or maybe the problem is the empty inconset ?
@ghys and @florian-h05 for discussing that.
Apparently if/iconify is not working in the item page but working in the other places.
material::favorite is not working but I am not sure if MainUI already supports Material icon source ? Or maybe the problem is the empty inconset ?
Yes, MainUI is (partially) working (like for iconify) using material::favorite:
So we have to synchronize and be OK with the 3 icon segments. My proposal is to use "material::favorite", that is "matelrial" as icon source, no icon set in that case and icon name "favorite".
"iconify:wi:day-sunny-overcast" means "iconify" as icon source, "wi" as icon set and "sunny-overcast" as icon name in this icon set.
To clarify, in my proposal, "material:favorite" is equivalent to "oh:material:favorite" and means requests the icon from the OH server with icon name "favorite" and icon set "material".
Here is a copy/paste of my proposal implemented in #3539 for items and #3378 for sitemap widgets.
The icon value can now contain until 3 segments separated by a semi-column. First segment is the icon source. Example: oh, if, iconify, material, ... Second segment is the icon set (and can be empty). Example: classic Third segment is the icon name (and can contain hyphen). Example: temperature
In case only two segments are provided, the icon source is assumed to be the openHAB server and the first segment is then the icon set and the second the icon name. In case only one segment is provided, the icon source is assumed to be the openHAB server and its classic icon set and the value is then the icon name.
That being said, that is just a question of choice. If you all prefer using material:favorite and f7:battery, then we can decide that when we have only 2 segments, the first segment is the icon source. I can then update my 2 core PRs and adjust Basic UI (very small change). This will avoid changing Main UI. In all cases, Main UI has to be enhanced to support values like oh:classic:lightbulb or oh:other_iconset:name, it is apparently not yet supported. @ghys @florian-h05 : WDYT ?
I finally changed the expectation when the icon value contains only 2 segments to be more compliant with Main UI syntax.
The icon value can now contain until 3 segments separated by a colon (":"). First segment is the icon source. Example: oh, if, iconify, material, f7, ... Second segment is the icon set. Example: classic Third segment is the icon name (and can contain hyphen). Example: temperature
In case only two segments are provided, the first segment is the icon source and the second the icon name. "classic" icon set is assumed. In case only one segment is provided, the icon source is assumed to be the openHAB server and its classic icon set and the value is then the icon name.
The results in MainUI:
- icon "temperature" => OK
- icon "oh:humidity" => OK
- icon "oh:classic:pressure" => KO everywhere in MainUI
- icons "material:arrow_drop_down" and "material:favorite": OK in items list page, OK in item edit page but KO in the item page
- icons "iconify:wi:day-sunny-overcast" and "if:wi:day-thunderstorm": OK in items list page, OK in item edit page but KO in the item page
@openhab/webui-maintainers: So I see two problems to fix in Main UI:
- the support of "oh:classic:value" as icon value
- the display of the icon in the item page for iconify and material icons
I also tested the rendering in the settings/model MainUI page, there is n surprise:
- Working icons: temperature oh:humidity material:arrow_drop_down material:favorite iconify:wi:day-sunny-overcast if:wi:day-thunderstorm
- Not working icons: oh:classic:pressure
I also tested in the equipment tab of MainUI (opening the "Web services" pop-up), the place where it is the most important and it looks like it was not implemented at all.
- Working icons: temperature
- Not working icons: oh:classic:pressure oh:humidity material:arrow_drop_down material:favorite iconify:wi:day-sunny-overcast if:wi:day-thunderstorm
Tested with these items:
Group GTest2 "Test items group 2" [ "WebService" ]
Number:Temperature CurrentTemp2 "Current Temp [%.1f °C]" <temperature> (GTest2) [ "Measurement", "Temperature" ]
Number CurrentHumidity2 "Humidity [%.0f %%]" <oh:humidity> (GTest2) [ "Measurement", "Humidity" ]
Number CurrentPressure2 "Pressure [%.0f hPa]" <oh:classic:pressure> (GTest2) [ "Measurement", "Pressure" ]
String CurrentPressureTrend2 "Pressure Trend [%s]" <material:arrow_drop_down> (GTest2) [ "Measurement", "Pressure" ]
Number:Temperature SetpointTemp2 "Setpoint Temp [%.1f °C]" <iconify:wi:day-sunny-overcast> (GTest2) [ "Setpoint", "Temperature" ]
Number:Temperature SetpointTemp3 "Setpoint Temp [%.1f °C]" <if:wi:day-thunderstorm> (GTest2) [ "Setpoint", "Temperature" ]
String TestString2 "Test string [%s]" <material:favorite> (GTest2) [ "Status" ]
@openhab/webui-maintainers : there is something to fix in MainUI.
In the updated syntax, I released the restriction to not have a hyphen in the icon name. This is because most of iconify icons have one or several hyphens in their names. In case a new openHAB iconset is created or even if a custom icon is added by the user in the classic iconset (just by downloading it from iconify for example), we should now accept icon name containing hyphen in openHAB iconsets.
The OH icon server supports two different syntax for requesting an icon:
- The state and the icon format can be passed in the path of the request URL like for example
../icon/humidioty-24.svg?iconset=classic
- The state and the icon format can be passed through the parameters "state" and "format" in the request URL like for example
../icon/humidity?state=24&iconset=classic&format=svg
.
In the first way, "-" is a separator to extract the icon name and the state. So there might be a possible mismatch in case the icon name now contains "-". One option would be to simply remove the first way to request the icon, that is passing the item state only through the "state" parameter and no more in the path. Basic UI is using only the way 2 so it will not be impacted by this change. @openhab/webui-maintainers @openhab/android-maintainers @openhab/ios-maintainers What is the status for MainUI, Android app and iOS app ?
Android also does option 2 only.
Code in both related PR LGTM, but if I have three questions:
- I understand that there needs to be an agreement on how iconsets are delivered, correct? What was the result of the discussion and how does it affect code in the
IconServlet
? - IMO there needs to be a big fat warning somewhere to prevent privacy issues when openHAB requests content from 3rd party servers somewhere on the internet. Where can I find that?
- Did someone check if this also works with the current iOS app? I would like to prevent shipping a milestone that has a big imbalance between the iOS and Android app.