Dashboard: Sort Tiles based on an Attribute Value?

Any way to do this ?

None that I’m aware of, but maybe you could find something by starting here…

When you say sort, what exactly are you referring to? Their x,y position on screen? Their position in a stack of tile (z-index)?

It may also help if we had some context on the scenario and what you are wanting to achieve. Perhaps even a mocked up screenshot.

Imagine the above, but with the tiles sorted by the date (oldest->newest) and any tiles with a date > 2 days before the current date with a red background

Not impossible to do with a custom app that generates its own dashbaord, but I'd say that there isn't a way to natively do that.

I can't say I've seen something like that done and would not be confident in it being possible

Why are you wanting to display them like that?

I'm guessing it's probably some version of last activity time... maybe looking for a device that hasn't reported in a while. If so, there are a couple of apps that, while they don't produce a dashboard, can give you/alert you with that information.

2 Likes

My head was going in a similar direction, thinking more so a chart.... But depends on the requirement.

@Thebearmay nailed the requirement. A simple visual view of devices that have not reported for a given period. Ideally long term add an action (click) would do a refresh, ping or whatever that forces a particular device to report-in

Device Watchdog would certainly be worth a look, I think, based on your description of what you are wanting to achieve.

Be aware that some devices are not able to be "tested" like you talk about. Certainly things like lights can be toggled on and off and then the last activity datetime checked, something I have done in the past. But some devices, particularly battery powered sensors, will report based (often) on how the manufacturer designed them to, with whatever options they offer to control the reporting, if any. I'm certainly not wanting to guide you away from pursuing this, just to keep this in mind and know that you may need to adjust your approach for some devices.

1 Like

As @sburke781 has said, you can't "ping" a battery powered end device. Device Watchdog can report on devices that have shown no activity in the last x hours (IIRC x is settable) and there is a special case for devices that are able to send a check in message which the app can also track.

The app can be set to poll at a specific time, however if you want to check say every 6 hours you can set up a rule to turn on a virtual switch at these times which toggles the app to run a report.

3 Likes

The same virtual switch can also be added to a dashboard to allow manual triggering of an update to the status reports, which is what I had at one time, automated report updates when I transitioned to Day mode, again in the afternoon (I think) and the manual option available if I wanted it.

1 Like

Yep that's what I do also ! Before anyone else asks the switch needs to be configured with the auto off function enabled. :grinning:

1 Like

I'm coming from Vera, and its dashboard had a 'devices no longer connected' tile. I was hoping to replicate that functionality somehow. I know a lot of people came from Vera, does anyone know how Vera was able to obtain (or guess) the state of battery powered devices.

I'd add to my / our earlier comments that it's not a flat "no" for battery powered devices. Perhaps one way to look at it is if you have either devices that are commonly triggered (motion sensor in a high traffic area) or commonly report something like temperature, then you should be able to get a good approximation for those that have either dropped off the network or their battery has run out. The issue is devices that don't report regularly and are not triggered on any consistent basis, e.g. a battery powered remote that is there to provide a manual control option in a motion controlled room.

I hope that helps.... And that other ex- cuurent-Vera users can also provide some background.

Got it !!!!

Thanks to @mbarone and this thread JS injection for Dashboard - :construction: Developers - Hubitat

I was able to inject a simple piece of javascript that did just what I wanted

(function() {0
    function pageStart(){
        //console.log("pageStart called");

        if(window.location.pathname.includes("device/edit")){
            // log to console that the script was injected properly, but stopped becuase we are on the device page
            console.log("JavaScript has been injected!  The script was stopped because it was injected into the device/edit page.  This should work on a dashboard.")
            // stop execution if we are on the device edit page, and not a dashboard.
            return;
        }
        /************************************/
        /* Add custom JavaScript below here */
        /************************************/
       
	    // Create an array containing the tile objects
        let tiles = Array.from(document.querySelectorAll(".tile",".attribute"))
		
		// Create an array containing each tile's id and value.
	    const lastUpdated = tiles.map((tile) => { 
	      return {id: tile.id, value: tile.querySelector(".tile-contents").querySelector(".tile-primary")?.innerText}
		})
        
		// Sort the array of tile ids by value
        lastUpdated.sort((a, b) => { return (a.value > b.value) ? 1 : -1})
		
		// Convert the array of tile objects into an object with the tiles keyed by id
	    tiles = tiles.reduce((object, tile) => { object[tile.id] = tile; return object}, {})
	
		// Remove the grid-area style from each tile and replace it with an order key.
		
     	const oneWeekAgo = new Date()
		oneWeekAgo.setUTCDate(oneWeekAgo.getUTCDate() - 7)
		const compareDate = new Date(oneWeekAgo.getTime() - (oneWeekAgo.getTimezoneOffset() * 60000 ))
		const compareValue = compareDate.toISOString().replace('T',' ').substring(0,19)		  
		
		lastUpdated.forEach((tile,idx) => {
		  const target = tiles[tile.id]
		  target.style.removeProperty('grid-area');
		  if ( tile.value === "" ) {
		    target.style.order = lastUpdated.length + 1
		    target.style.display = "none"
		  }
		  else {
		    target.style.order = idx 
			if (tile.value < compareValue) {
			target.style.setProperty("background-color","red");
			}
		  }
		})
		
	
        //console.log("pageStart ended");
    }
    pageStart();
})();

type or paste code here

4 Likes

Doesn't seem to work on a mobile device, eg when viewed in the Hubitat app.

How does it not work? i.e. what are you seeing or not seeing? I can only imagine either the DOM is a different structure somehow or the events are different.

Cool. How do you use this script?