[RELEASE] HousePanel Dashboard for SmartThings and Hubitat

Cool work. I started using Font awesome for modern but ended up switching to the noun project. Both are good resources. On the date format used in the event history, good idea. I could even make it a user input field with this as the default.

Revision 2.056 pushed tonight with update to specify the format of the event date in the Groovy authentication step. The default is as @rsb noted above - really great suggestion. With this update the auth step includes a new question to optionally specify the format of the event date field.

Thank you! You have fixed whatever was preventing a vertical display. Still does not quite match up with the display, but I should be able to figure that out.

Good work. Can you share what changed so I can learn?

Look in the tileeditor.css file near the top - lines 27 through 48. Here you will see orientation dependent styling. It looks like:

@media (orientation: landscape) {
body {
width: 1200px;
}
#dragregion, #dragregion div.panel {
min-height: 700px;
}
.ui-tabs .ui-tabs-nav .ui-tabs-anchor {
font-size: 11pt;
}
}
@media (orientation: portrait) {
body {
width: 750px;
}
#dragregion, #dragregion div.panel {
min-height: 1000px;
}
.ui-tabs .ui-tabs-nav .ui-tabs-anchor {
font-size: 10pt;
}
}

To make it fit your tablet, adjust the parameters above. I also had to remove a few other width settings and change them to percentages so the body width always dictated the size. The lesson here is control the visible size in one place with a media tag and use percentages everywhere else. The one exception I took was on the Show Info page where a portrait size just doesnā€™t work. In portrait mode you will just need to scroll left and right, but then again, I would expect portrait to only be used in a wall display, not on the master controller which is strongly recommended to be a PC. The model I recommend is that people edit the setup on a PC and deploy on tablets by turning on Kiosk Mode to prevent end users from making changes.

Just got my 4 year anniversary badge - although it has been 4 and 1/2 years. Not sure why they shifted January to May. Anyway, hard to believe it has been this long. I started developing HP one year in so HP is now 3 years old. How time flies. Development has slowed down so most of my effort will now be on making a real website for it with better support info. I would love to know how many people are actively using it. Is there an easy way to poll people here for this sort of thing. I can see how many downloads there are but that doesnā€™t equate to active users.

There may be some mechanism through the folks that control the ST IDE, since all active users will have the groovy file installed ā€” no suggestions on the Hubitat side.

I would be happy to provide editorial help on the documentation.

I humbly suggest putting in a code block that does a ā€œcheck-inā€ to a simple unique IP address counter (or use the SmartThings Location ID - you can hash it on the client side - to ensure it is anonymous).

While such code may let you track the IP addresses of the instances calling it, you could just promise to delete the web server logs.

Iā€™m sure a simple PHP script exists? Using Google Analytics would be much more invasive and unnecessary.

Nifty idea that should work since I do have a registered HP domain where the service could be hosted. My only hesitation is some of my user base is fanatical about local processing. For ST it isnā€™t an issue since the cloud is required but for my Hubitat users some might complain (even though I currently load jQuery and some icons from the cloud). I suppose this is just tough cookies since the ping would be tiny and the code is free. Heck I could even wire up my donate button to remove the ping - Iā€™m still searching for a way to embed PhP code that isnā€™t end user visible for stuff like this. So many possibilities- thanks for getting my ideas flowing on this.

Answering my own question here with the following info I just found:
ā€”ā€”ā€”ā€”
You can obfuscate but you cannot hide completely. Iā€™ve been forced to use both ionCube and Zend Guard before, which perform this obfuscation, and there is no big difference between them. These products precompile your PHP files to bytecode (opcode) and ship only the bytecode in an encrypted container. At runtime a loader (which you must enable on the server) decrypts the bytecode and inserts it into memory.
ā€”ā€”ā€”ā€”-
So question for my user base: would anyone be terribly annoyed if I switched to this type of distribution model?

You donā€™t need or want the code to be hidden, I think.

The call to your tracking server can be explicit plain code, but require a ā€œuser API keyā€ (generated from a form on your website) to be valid, or generate a random token and store it as a cookie so that the same one continues to be used (though I recommend hashing the Location ID instead).

Users who are more concerned about privacy rather than helping support HP with this minimally invasive tracking (NB: It does not make the system not run local - it is an optional outgoing call), can simply delete that section of code.

As far as I know - though I have not extensively researched - this sort of trivial phone-home tracking is common in a lot of open source projects. It is not considered nefarious nor onerous because it is fully disclosed.

We can chat offline about this suggestion, in case Iā€™m not explaining it clearly enough to get the picture.

Your explanation is completely clear and very much appreciated. I also donā€™t like the idea of hiding the code via a Zend compiler so everyone can ignore that idea.

1 Like

6 years for me. Iā€™m likely among the longest survivors (Kickstarter backer and original WordPress Forum user).

1 Like

My next feature request is adding album art to the music player tiles. This will work out of the box when you install Echo Speaks and make a few changes here:

HousePanel.groovy around line 362:

name: item.displayName,
trackImage: item.currentValue(ā€œtrackImageā€),
trackDescription: item.currentValue(ā€œtrackDescriptionā€),
currentArtist: item.currentValue(ā€œcurrentArtistā€),
currentAlbum: item.currentValue(ā€œcurrentAlbumā€),
status: item.currentValue(ā€œstatusā€),
level: item.currentValue(ā€œlevelā€),
mute: item.currentValue(ā€œmuteā€)

housepanel.php around line 1869

} else if ($tkey===ā€œtrackImageā€) {
$tc.= ā€œ<div type=ā€$thingtype" subid=ā€œtkeyā€ id=ā€œa-$i-$tkeyā€ style=ā€œbackground-size: cover; background-repeat: no-repeat; background-image: url(ā€ . urldecode($tval) . ā€œ)ā€>";
} else {
if ( substr($tval,0,6)===ā€œRULE::ā€ && $subtype!==ā€œruleā€ ) {

(That last line with RULE is in there to be sure you know where this goes)

housepanel.js around line 1814 (first and last lines just there for context again)

// setupColors();
} else if ( key===ā€œtrackImageā€) {
value = ā€œ<div id=ā€" + targetid + ā€œā€ style=ā€œbackground-size: cover; background-repeat: no-repeat; background-image: url(ā€ + value + ā€œ)ā€>";
// special case for numbers for KuKu Harmony things

and finally in my theme/housepanel.css file

div.trackImage div {
height: 180px;
width: 180px;
}

One other small comment is that echo speaks (which is great by the way) has a bug where they are returning the wrong field values in the API. When they fix that, this should all work seamlessly. In the meantime, the artist and album may not show up correctly.

I guess at some point I should get myself setup in git so I can make requests like this easier for you. Apologies for the hassle until then.

This is really a great suggestion - and you have correctly deciphered how the HP architecture works. Really good stuff. I have installed Echo Speaks and I love it too. However, I canā€™t get it to work consistently with all audio apps. For example, I canā€™t get Big Talker to make my echo units talk although Sonos talks fine. I assume the field will work fine with Sonos devices too. I will try it out and report back. I do accept pull requests so if you do set up a Git account it will make it easier and you can also get public credit for making a contribution to HP. At present only one other person has done this successfully - the original author of TileEditor - @nitwit who has disappeared from the forum.

Regarding your suggested changes, I think they are brilliant. I will probably tweak the official implementation to leave styling to the CSS file and to the TileEditor while adding the url into the code as I do today with image tiles.

Thanks again for this great suggestion and stay tuned to see it implemented.

So Iā€™m checking the legacy ST documentation and the only attribute fields I am finding for MusicPlayer (which by the way they say is deprecated) are the original fields in HP plus one that I skipped called trackData. I donā€™t see trackImage, currentArtist, or currentAlbum. They of course could be there if the DTH adds them which I assume Echo Speaks does. So I will likely check for hasAttribute and add them if there.

Does anyone know what the alternative non-deprecated version of this capability is called?

1 Like

So here is what I foundā€¦ I changed my getMusic function to the generic ā€œgetterā€ which returns all supported attributes, and the Echo Speaks devices return a bunch of commands but they donā€™t return the fields named above. Sonos devices return only the default with a bunch of Sonos proprietary stuff in the trackData field. Here is what Sonos and Echo devices look like minus the trackData field:

So I am concluding that the best option is to parse the trackDescription field to grab an artist name, and then find a suitable Album art using a web search. This will be super cool but will take some time and effort. Stay tuned.

1 Like

currentAlbum, currentStation and trackImage should be set by echo speaks:

https://tonesto7.github.io/echo-speaks-docs/#/docs/devices/deviceAttributes

However currentAlbum actually is the artist, which Iā€™ve corrected in my local copy of Echo Speaks and submitted a bug report. currentStation is sometimes the current station and sometimes the current album. I have guesses why thatā€™s the case but canā€™t verify. Regardless, I think calling it currentAlbum makes the most sense. I donā€™t use sonos anymore, so unfortunately canā€™t help there. It seems like a lot more work than Echo Speaks, not sure itā€™s worth your time unless you really want this feature. Thanks again.

I just checked and sure enough, I have an old version of echo speaks that didnā€™t have this feature. I will upgrade. With that said, there are many music player device types out there and not all will support this as it is not a standard attribute. The trackDescription is standard so the update I proposed will work with Sonos and any other valid music player device, including echo speaks.

The code to extract the artist and album names is done and working great. Now the hard part of finding a reliable service to find and return an album art image. A simple Google search will usually work so I might go this route.

1 Like

Hereā€™s the routine I wrote to extract the first icon found by a Google search. It uses the same curl_call function used by the rest of HP so the only incremental code is the small getImage PHP function.

<?php

function curl_call($host, $headertype=false, $nvpstr="", $calltype="GET")
{

    $debug = "host= $host header= $headertype nvpstr = $nvpstr calltype= $calltype";
    
    //setting the curl parameters.
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $host);
    if ($headertype) {
    	curl_setopt($ch, CURLOPT_HTTPHEADER, $headertype);
    }

    //turning off peer verification
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_VERBOSE, TRUE);

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    if ($calltype==="POST" && $nvpstr) {
    	curl_setopt($ch, CURLOPT_POST, TRUE);
    	curl_setopt($ch, CURLOPT_PUT, FALSE);
    } else if ($calltype==="PUT" && $nvpstr) {
    	curl_setopt($ch, CURLOPT_POST, FALSE);
    	curl_setopt($ch, CURLOPT_PUT, TRUE);
    } else {
    	curl_setopt($ch, CURLOPT_POST, FALSE);
    	curl_setopt($ch, CURLOPT_PUT, FALSE);
        // curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $calltype);
    }
    if ($nvpstr) { curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpstr); }

    // getting response from server
    $response = curl_exec($ch);
    curl_close($ch);

    return $response;
}

function getImage($artist, $album) {

    $query = "https://www.google.com/search";
    $nvpstr = "as_st=y&tbm=isch&as_epq=" . urlencode("$album by $artist");
    $tc = curl_call($query . "?$nvpstr");

    // get the location of the first image returned by Google
    $ipos = strpos($tc, "table class=\"images_table\"");
    if ( $ipos ) {
        $imgpos = strpos($tc, "<img", $ipos);
        $imgend = strpos($tc, ">", $imgpos);
        $image = substr($tc, $imgpos, $imgend - $imgpos + 1);
    } else {
        $image = "No Image Found";
    }
    return $image;
}

    echo '<!DOCTYPE html>';
    echo "<html><head><title>HousePanel Image Test</title>";
    echo "</head><body>";
    echo "<h2>HousePanel Image Test</h2>";
    
    if ( isset($_GET["artist"]) ) {
        $artist = $_GET["artist"];
    } else {
        $artist = "Buckethead";
    }
    
    if ( isset($_GET["album"]) ) {
        $album = $_GET["album"];
    } else {
        $album = "Boiling Pond";
    }
    
    $image= getImage($artist, $album);
    echo $image;
    echo "</body></html>";

Next step is to get this integrated into HP, but thought I would share this nifty bit of fancy footwork

ā€” EDIT ā€”
An initial proof of concept Integration was super easy. Hereā€™s a preview. Still need to implement updates in the js file and do some battle testing so stay tuned for the official release. I picked a random play list on purpose to confirm it works for oddball stuff too. I have no clue who this artist is.

image

Okay folks - I posted Version 2.060 tonight with the music Album Art auto grabber fully implemented and integrated. Here is what it looks like:

image

Big thanks to @rsb for the initial idea and inspiration for this. I ended up implementing this in a generic way that uses a Google search for the first icon returned that is square and small. This works the majority of the time but is not a perfect algorithm. It is possible you will be weird results or no results for obscure albums. So far I have found it works pretty well. The way this works is I parse the Track Description for Album name and Author name, and then I do a CuRL call to Google and then grab the first image returned. Pretty slick I think. The Echo Speaks DTH gives an album art text field directly but I donā€™t use that because it isnā€™t portable over to other Music devices.

1 Like