Hopefully this hasn’t been requested as I did look to see if it was possible, but I’m adding my request for support for long press (and maybe even hold) on tiles.
I created a dashboard the replicated my remotes for full control of my entertainment system. The buttons on the remote support both press and long press.
I am using HTTP calls to execute .runrule() with a parameter of the button to be pressed for each tile. The rule then parses the parameter and executes the proper command on the proper device. (I’m really over simplifying).
It would be nice if I could call one HTTP for press and another for long press. What may also work is the ability to know if it was a press/long press as an even variable that I could act on in the rule and then act on it there instead.
I’m just throwing the idea out there as I always know implementation is much harder that it seems.
Are you currently doing this with Hyperlink tiles or some other type of tile (which offers hyperlink as an action)?
You could also accomplish this with a Custom Tile, but it would require a bit HTML/JS. The upside of this is you could even create a custom layout to mix multiple ‘buttons’ together in a layout you deem appropriate.
So right now, because I was working on a POC to get this working with my back end, I was using the variable tiles and putting the html link in the on tap field.
I would be interested in doing this with the HTML/JS. Unfortunately I don’t know where to start with that but if you have an example I would love to give it a shot.
What I execute right now is “$.runRule(“RULEID”, {“command”: “volumeUp”})”. In the rule it will first determine the dashboard that it was sent from, and based on that would know which of the remotes to send it to and will trigger the harmony hub to send the command.
I mainly did it this way so I can clone the dashboard without having to recreate everything multiple times (its a lot of tiles). It works really well… I just want to add in the long press so I could cover everything exactly like the remote?
I can try to mock something up for you as a starting point if you’d like.
In the meantime, you might use something like the following for adding the long-press event:
Instead of the $.runRule() special hyperlink syntax, you would have to add an HTTP Trigger to your rule and call that directly.
The JavaScript for making calling the HTTP Trigger might look something like:
//the base rule HTTP trigger URL
let ruleUrl = "https://trigger.sharptools.io/rule/RULEIDHERE/key/http-trigger-key-uuid-here";
//and layer in your parameters (which you can access in the rule)
let targetUrl = ruleUrl + `?command=channelUp&remote=livingRoom`
//call the rule
fetch(targetUrl, {mode: 'no-cors').then(()=>{
console.log("rule execution sent");
}).catch((error)=>{
console.error("rule execution failed to send", error);
})
Since you won’t have the context of the dashboard, you’ll probably want to add another parameter and use that as your context.
Edit: there’s some example tiles in the community projects category you might like to use as a reference as well
When you add the tile to your dashboard (or preview it), you have to edit the settings and add in the URL to your rule and optionally add a ‘remote’ value so you can identify which remote the command is for.
You could extend the concept to make the whole set of buttons a configurable JSON string if you wanted, but I just wanted to put the concept together for you.
The buttons variable defined toward the top of the script defines the buttons that are displayed. Again, it’s just a proof of concept, so feel free to adjust as you see fit. The format of each button is:
Thanks again. Was playing around with it this morning and looks like the direction I should go.
I know in your custom tile you create all the tiles. However is there a negative (performance or other reason) to using the custom tile for just a single tile and adding a bunch of them to the dashboard?
Mainly thinking of being able to lay them all out exactly how I want it which seems a little more difficalt if I added all the tiles to the single custom tile.
No major performance considerations. I was originally just thinking that you might create a single large tile as a ‘controller’ and you could use HTML/CSS to position the buttons on the custom tile exactly as you wanted. The Custom Tiles are a tick slower to load than normal tiles when you open a new dashboard as they render in a separate secure context, but you can play with that to get a feel for it.
I didn’t actually show it in the example as I was more focused on the control side of things, but you could get more control aligning things in unique ways (buttons between buttons, small power button, slim action buttons, etc).
But yeah, doing it as individual commands to the rule could work well too.
Got it all up and running. Just doing some visual clean up now to make it look like a single tile. This takes me time as my JS coding isn’t strong so I hack a lot.
Is there a way to add the icon option in the settings so you can set the icon like other tiles?
Sort of, but not the traditional icon picker. You could add an icon setting to the custom tile, but you would have to type in the name of a Font Awesome 6 (free/solid) icon.
With the icon, I reference it in the html code but I think the tile is being rendered before the data settings are available for use. So I’m guessing I then need to dynamically update the icon on the tile in the “ready” method correct?
If so any idea how I could do that? Or is that the wrong direction.
Yeah, you’re getting into a slightly tricky space with reactivity though. (And I may have complicated the example by using Vue as a JS framework, but I just love it and couldn’t help myself.)
Font Awesome replaces the <i class="fas fa-icon"></i> with an SVG automatically… but when Vue tries to react to the icon change and patch the DOM, it can’t find the original <i> element anymore since Font Awesome replaced it.
So you’ll want to wrap the <i> tag with a keyed <div> so it can be patched properly:
Took me a while (my JS skills aren’t strong) but got things up and running and working. The long/short press all work nicely and I was able to duplicate my remote onto a dashboard. This is good for those times the battery dies. Much better than the harmony app.
Just a few more questions if you don’t mind.
I noticed the icons sometimes take a few seconds to load when the page loads. Is that because its downloading them from font awesome? Any way to speed that up? With regular tiles the icons alread exist.
Is there some way to reference a variable, either a global variable or something stored on the dashboard, inside of the custom tile? Every tile has the same values for rule ID for example, but if it every changes I will have to change them all.
On a similar note is there a way to access the name of the dashboard?
Lastly, is there a way to set default values for a tiles settings?
On a side note, I took this custom tile concept and also created a custom BlueIris tile with some controls for my camera. Still working on the JS for it but the goal is to integrate the cameras nicely so I only have to load the app to view past events which is done via one of the icons and an iOS intent. Maybe later I’ll add the code for the event list. But for now I can control the floodlight, trigger for recording or go full screen for the stream all without leaving the dashboard.
If you want to PM me the code, I’d be happy to take a look. Ideally, the icons and javascript should be coming from sources that get cached in your browser so they shouldn’t need to download each time. My gut would suspect other parts of the Custom Tile lifecycle – in general, they take a tick longer to render since they render in a separate context (as noted above)… when waiting for the stio.ready() callback, that adds a bit of delay too as it waits for the DOM to be completely loaded before it will get that callback.
There’s not currently a way to access the name of the dashboard since the Custom Tiles are sandboxed, but feel free to create a feature request. I suppose the ‘context’ of the tile could be passed down.
There’s a few different approaches. In the sample code, I used two approaches:
You can initialize your local variables to whatever value you want… then if the setting isn’t reported from the stio.ready() callback, you could leave the default value to be used (eg. the isNullOrEmpty() type checks I used).
It’s not officially documented, but you can add a ‘default’ property into a setting in the ‘Do not edit below’ section. The parsing of that section is only triggered when the setting keys change – it was primarily intended for importing… so you have to either add or remove a dummy setting, then tab out for the new values to be parsed (and then remove/readd it).