Hubitat HTML Attribute Display

This is a proof-of-concept for displaying HTML Attributes from Hubitat in a Custom Tile.


:man_technologist: This is one of several sample tiles that were built as part of the Custom Tiles release and is not intended to be a fully polished tile. Please feel free to learn from it, copy from it, or play with it.


What does it do?

Some community developed Hubitat device handlers use a ‘hack’ in which they stuff device attributes with HTML to enable them to display data as tables or embed images.

The Hero Attribute tile would normally display the HTML as text as a security precaution:

This tile can render the HTML and display embedded images/tables in a separate secure context:


Enable Hubitat Maker API

Follow the steps below to enable Maker API in Hubitat admin page.

  • Install the Maker API app and select the device(s) that you want to display
  • Enable Allow Access via Remote/Cloud
  • Add in the Allowed Hosts (for CORS) field
  • Scroll down and copy one of the example cloud endpoints
  • Make sure to press Done to save your changes!

Create Custom Tile

  • Tap the Import button above to import the tile, then scroll down and save the tile
    • Optionally, press Preview to try out the tile without saving (you’ll need the details from the Enable Hubitat Maker API section above)
  • Go to the desired dashboard, Edit, and Add Item. Tap “Custom Tile” in the Other section and add this custom tile.
  • Edit the tile, fill-in the settings, and save:
    • Sample Maker API Url - use one of the Hubitat Maker API Cloud endpoints
    • Device ID - enter the ID of a device with an attribute stuffed with HTML
      • Note that you can find the device ID in the URL of your browser when you are viewing a devices details within the Hubitat Admin UI page
    • Attribute - enter the name of the attribute that is stuffed with html

Video Demo

Setup Hubitat Maker API

Import and Configure Custom Tile

1 Like

I like how the native sharptools tiles scale the font size as the overall dashboard is scaled. What HTML/CSS in a custom tile will achieve the same effect? I’ve tried defining font size in percent, em, etc. but no luck.

You could use a style which scales thing relative to the tile container (viewport):

.your-class {
   /* simplistic font autoscaling */
   font-size: min(15vh, 15vw); 

This scales the font based on the height (vh) and width (vw) of the tile container. You might also only want to scale based on one of the dimensions in which case you can just do something like:

.your-class {
   font-size: 15vh; /* scale relative to the tile height */
1 Like

Perfect. That did it. Thanks!

1 Like

I just tried this out and got it to work fine when I targeted a specific tile, the clock tile.

However when I apply it generically to my theme I can’t seem to get it working.

I have the following commands at the beginning of my theme to target all tiles:

.tile .title { top:70%; font-size: 15vh; }
.tile .icon svg {width: 55%; height: 55%; margin: 0; position: absolute; top: 30%; left: 50%; transform: translate(-50%, -50%);}
.tile .tile-footer { text-align: center; bottom: unset; top:85%; }
.tile .tile-footer .status span.right { float: inherit!important; }

When I insert the relative font size command it doesn’t seem to do anything with the size of the title. Usual caveat, I am teaching myself (or more accurately the community here is teaching me) css so apologies if I missed something obvious.

The style snippets posted above are for a developer to use within a Custom Tile.

The custom tiles render in their own context, so they don’t inherit all the aspects of a normal tile like font scaling. On the other hand, normal tiles dynamically get their font sized, so for Custom CSS in a Theme you’re generally better off using a font-size relative unit like em.

In theory, viewport relative units like those used above could be used in Custom CSS - you might want to read up on viewport units if you’re interested in what they are and how they work. :slight_smile:


As advised, I’ll post here instead of over at the hubitat forums (this thread, [RELEASE] Life360 Tracker - Works with the Life360+ app! - #426 by djh_wolf - Custom Apps - Hubitat)

That guy has made a pretty awesome set of apps. One of which links into his own life360 driver, which allows for all sorts of info to be pulled from life360 devices.

eg. this is my presence sensor (my mobile):

What I’m most interested for this discussion, is the ‘list of recent locations’ part, i.e.:


Here’s an example of how a tile can look with the standard hubitat dash.

However, if I try to pull the info from my device’s bpt-history, and display it on a tile in sharptools, I get the html code instead:

I can’t quite figure out how to use this thread to help me accomplish the task. Apologies =p

Thanks for posting! Can you share more details about what you’ve tried so far? There’s instructions in the first post explaining how to set up and use this custom tile – is there a particular step you got tripped up on?

Edit: I mentioned it over in the Hubitat thread, but I’ll mention it here as well in case anybody else finds this post. There’s also a community developed Life360 map for SharpTools for anyone who is looking for an interactive map on your dashboard.

1 Like


Done this already:
Got could endpoint:

hxxs://[Device ID]?access_token=65f4d69f-ad17-xxxxxxxxxxxxxxxxxb86dcf6

and device id for life360 device
{“id”:“2051”,“name”:“Life360 - darren”,

Clicked preview, added the info as this screenschot:

…hah, and now it works. I was obviously doing something stupid.

-=edit=- doesn’t work. preview looks ok…

but when i try to add the custom tile to the dash…

1 Like

Thanks for the details. Sounds like you made progress!

So the preview in the developer console is mainly for developers as they are building a tile or for you to preview it before it’s actually used.

The settings in the preview window from the developer console are just temporary and are not saved with the custom tile.

Once you add a tile to the dashboard, you’ll want to edit that individual tile instance on your dashboard and copy the same settings that you used for your preview over.

1 Like

Cheers josh. Makes sense. Tested and managed to get to this…

There are no scroll bars, and I can’t figure out how to make the text a decent size which would flow better with my scalable dash.

Any ideas? Ta!

Awesome! Sounds like you got it working!

Custom tiles (and regular tiles) don’t have scroll bars, but if the content is scrollable you should still be able to scroll it either with a scroll wheel on a mouse, a touch pad, or a touch screen. That being said, this tile was originally designed around showing HTML content that would be vertically centered in a tile – like the weather example shown in the first post – so it wouldn’t surprise me if long scrolling content might not work well without some tweaks.

This tile was intended as a proof-of-concept – it’s not intended to be a fully polished tile and was really just something for the community developers to learn from and adapt to their needs.

Either the source html attribute from Hubitat would need to offer font scaling or someone would need to modify the custom tile to accommodate font scaling.

That being said, you could modify the custom tile to meet your needs if you want. Toward the bottom of the custom tile code, you could adjust the <style> block. Note that this will adjust the style of all your instances of this custom tile.

In this example, we’ve commented out the align-items: center, so it doesn’t try to vertically center things (you could also just delete this line). Then we added a font-size that scales with the size of the tile. You could just just use a static font size as shown in the next commented out line which is often more appropriate with content like this.

  html,body {height: 100%;margin:0;}
  .main-content {
    display: flex;
    /* align-items: center; */ /* don't vertically center */
    justify-content: center;
    font-size: 20vh; /* viewport height relative sizing */
    /* font-size: 2em */ /* or use a bigger default font, but not one that scales with the size of the tile */
  .main-content #content {
    text-align: center; /* OPTIONAL center align any text that gets injected */
  .main-content #content img {
    max-width: 80%; /* OPTIONAL scale any inner images if they're too big */
1 Like

Hi there,

This bit of code has been a lifesaver. Thank you!

One thing happening that I really don’t know how to get around and hoping someone can help me out.

I have a Hubitat HTML element on my Netamo Weather Station device that renders a small arrow icon in the Hubitat Device Summary depicting wind angle. When I use this custom tile to import that summary onto a tile in SharpTools everything renders perfectly, except those arrows. See images.

As you can see the only difference is the (crucial) arrows are missing. When I inspect the code on the Hubitat page by my rudimentary understanding it seems reference a “Material Icons” font. I’m thinking this is what is not porting over. The font info is here: Material Icons Guide

I’d sincerely appreciate any hints on how I might be able to get this to work and reflect those icons, if that’s possible. Thank you!

Based on their documentation, it sounds like you could try adding the Material Icons font import to the top of your custom tile:

<link href=""

For example, the Hubitat HTML Attribute custom tile could be modified like so:


I could have read little further down the page! Thanks Josh for pointing out what I should have found for myself. Unfortunately this doesn’t seem to work but I will tinker. Thanks again.

Can you share a snippet of the raw HTML from the attribute?

I think what you’re looking for is in this block

 <div class="mdl-card__title">
                        var deviceId = 414;
                        var currentStates = {"zigbeeId":null,"deviceTypeId":654,"currentStates":{"soundPressureLevel":{"floatValue":47.0,"jsonValue":47,"value":"47","deviceId":null,"dataType":"NUMBER","unit":"db","date":"2021-12-06T19:05:32+0000","stringValue":"47","id":null,"numberValue":47,"doubleValue":47.0,"name":"soundPressureLevel"},"pressure_trend":{"value":"down","deviceId":null,"dataType":"STRING","unit":null,"date":"2021-12-06T18:35:32+0000","stringValue":"down","id":null,"name":"pressure_trend"},"sound":{"value":"detected","deviceId":null,"dataType":"ENUM","unit":null,"date":"2021-12-03T19:01:10+0000","stringValue":"detected","id":null,"name":"sound"},"temp_trend":{"value":"stable","deviceId":null,"dataType":"STRING","unit":null,"date":"2021-12-06T19:05:32+0000","stringValue":"stable","id":null,"name":"temp_trend"},"carbonDioxide":{"floatValue":441.0,"jsonValue":441,"value":"441","deviceId":null,"dataType":"NUMBER","unit":"ppm","date":"2021-12-06T19:05:32+0000","stringValue":"441","id":null,"numberValue":441,"doubleValue":441.0,"name":"carbonDioxide"},"Overview":{"value":"<div style='line-height: 0.95; font-size: 0.75em;'><br>Indoor:&nbsp;20.8&deg;C@33%RH<br><div style='line-height:50%;'><br></div>Outdoor:&nbsp;-15.3&deg;C@54%RH<br><div style='line-height:50%;'><br></div>Wind: 7 kph<i class='material icons he-arrow-down-left2'></i>&nbsp;(16 kph<i class='material icons he-arrow-down-left2'></i>)<div style='line-height:50%;'><br></div>Rain:&nbsp;0.0 mm&nbsp;&nbsp;CO2:&nbsp;441ppm<div style='line-height:50%;'><br></div>ATM:&nbsp;1020.5mbar&nbsp;&nbsp;SPL:&nbsp;47db<br></div>","deviceId":null,"dataType":"STRING","unit":null,"date":"2021-12-06T19:05:32+0000","stringValue":"<div style='line-height: 0.95; font-size: 0.75em;'><br>Indoor:&nbsp;20.8&deg;C@33%RH<br><div style='line-height:50%;'><br></div>Outdoor:&nbsp;-15.3&deg;C@54%RH<br><div style='line-height:50%;'><br></div>Wind: 7 kph<i class='material icons he-arrow-down-left2'></i>&nbsp;(16 kph<i class='material icons he-arrow-down-left2'></i>)<div style='line-height:50%;'><br></div>Rain:&nbsp;0.0 mm&nbsp;&nbsp;CO2:&nbsp;441ppm<div style='line-height:50%;'><br></div>ATM:&nbsp;1020.5mbar&nbsp;&nbsp;SPL:&nbsp;47db<br></div>","id":null,"name":"Overview"},"pressure":{"floatValue":1020.5,"jsonValue":1020.5,"value":"1020.5","deviceId":null,"dataType":"NUMBER","unit":"mbar","date":"2021-12-06T18:55:32+0000","stringValue":"1020.5","id":null,"numberValue":1020.5,"doubleValue":1020.5,"name":"pressure"},"min_temp":{"floatValue":16.4,"jsonValue":16.4,"value":"16.4","deviceId":null,"dataType":"NUMBER","unit":"C","date":"2021-12-06T09:20:32+0000","stringValue":"16.4","id":null,"numberValue":16.4,"doubleValue":16.4,"name":"min_temp"},"temperature":{"floatValue":20.8,"jsonValue":20.8,"value":"20.8","deviceId":null,"dataType":"NUMBER","unit":"C","date":"2021-12-06T19:05:32+0000","stringValue":"20.8","id":null,"numberValue":20.8,"doubleValue":20.8,"name":"temperature"},"humidity":{"floatValue":33.0,"jsonValue":33,"value":"33","deviceId":null,"dataType":"NUMBER","unit":"%","date":"2021-12-06T18:35:32+0000","stringValue":"33","id":null,"numberValue":33,"doubleValue":33.0,"name":"humidity"},"Summary":{"value":"<div style='line-height: 0.95; font-size: 0.75em;'><br>Indoor:&nbsp;20.8&deg;C&nbsp;-&nbsp;stable<br><div style='line-height:50%;'><br></div>Min&nbsp;/&nbsp;Max:&nbsp;16.4&deg;C&nbsp;/&nbsp;21&deg;C<br><br>Humidity:&nbsp;33%&nbsp;&nbsp;CO2:&nbsp;441ppm<br>ATM:&nbsp;1020.5mbar&nbsp;&nbsp;SPL:&nbsp;47db<br></div>","deviceId":null,"dataType":"STRING","unit":null,"date":"2021-12-06T19:05:32+0000","stringValue":"<div style='line-height: 0.95; font-size: 0.75em;'><br>Indoor:&nbsp;20.8&deg;C&nbsp;-&nbsp;stable<br><div style='line-height:50%;'><br></div>Min&nbsp;/&nbsp;Max:&nbsp;16.4&deg;C&nbsp;/&nbsp;21&deg;C<br><br>Humidity:&nbsp;33%&nbsp;&nbsp;CO2:&nbsp;441ppm<br>ATM:&nbsp;1020.5mbar&nbsp;&nbsp;SPL:&nbsp;47db<br></div>","id":null,"name":"Summary"},"lastupdate":{"value":"13:02","deviceId":null,"dataType":"STRING","unit":null,"date":"2021-12-06T19:05:32+0000","stringValue":"13:02","id":null,"name":"lastupdate"},"max_temp":{"floatValue":21.0,"jsonValue":21.0,"value":"21.0","deviceId":null,"dataType":"NUMBER","unit":"C","date":"2021-12-06T18:35:32+0000","stringValue":"21.0","id":null,"numberValue":21.0,"doubleValue":21.0,"name":"max_temp"}},"groupId":null,"parentDeviceId":null,"name":"NAMain.70:ee:50:71:45:86","id":414,"label":"Weather Station","deviceNetworkId":"70:ee:50:71:45:86","lanId":null,"version":2,"driverType":"usr"};
                        var layout = {};

                        $(document).ready(function () {
                            //loadUI(deviceId); //may need this back and device.js

Wind: 7 kph<i class='material icons he-arrow-down-left2'></I>

Which renders this:

Screen Shot 2021-12-06 at 9.12.14 PM

Thank you!

Hi Josh,

Since I’ve struck out in my own research was wondering if the code below is helpful for diagnosing what could be going wrong? Thanks and appreciate the help.

It looks like it’s not a standard Material Icon being used. Based on the name he-arrow-down-left2, it seems like it’s a custom icon included by the Hubitat team.

If it’s just arrow icons being used, you could add some CSS in the tile to use normal arrow characters. For example, the following would fix the particular arrow from your example:

  .he-arrow-down-left2 {
    content: "↙",

I’m taking an educated guess that the following snippet should cover all the arrow combinations. If that doesn’t cover them all, I would need to see a copy of the driver’s code to see any other icons. :slight_smile:

.he-arrow-down-left2:before {
    content: "↙"
.he-arrow-down-right2:before {
    content: "↘"
.he-arrow-down2:before {
    content: "↓"
.he-arrow-left2:before {
    content: "←"
.he-arrow-right2:before {
    content: "→"
.he-arrow-up-left2:before {
    content: "↖"
.he-arrow-up-right2:before {
    content: "↗"
.he-arrow-up2:before {
    content: "↑"

Dude - you’re amazing. Will give it a go tomorrow. Thank you!!

1 Like