Audio Track Attributes - Parsing or SmartThings 24 API Token

Hello friends,

I am new to SharpTools and have been using it for only a couple of months. During this time, I have managed to create some beautiful dashboards to control my devices and read data from my sensors. Thanks to this amazing community, I was able to learn a lot faster and am very happy with my progress so far. However, I’ve hit a roadblock, and I need your help!

I am struggling with the 24-hour expiration of the SmartThings API token, and it’s preventing me from moving forward. My brain is melted trying to figure this out. :sweat_smile:

Here’s the issue:
I’m building a Super Tile to display information from my Sonos (IKEA) speakers. I use a rule to fetch data from the SmartThings API and write it to text variables. Unfortunately, the personal access token expires after 24 hours, which causes my Super Tile to stop working.

Does anyone know how to solve this issue or make the API token last longer? Any help would be greatly appreciated!


I might be missing something, but I don’t understand all the extra complexity around trying to use the SmartThings API to retrieve device details…

Why not just add the device attributes directly to the Super Tile? SharpTools will automatically take care of setting up all the event listeners and making sure the data stays fresh (in realtime) on the tile.

Edit: On second readthrough, I see that you are using data from the audioTrackData attribute which is a bit unique compared to normal attributes.

Rather than having a single value directly in the attribute, the device stores a JSON Object with additional properties like album, artist, title`, etc.

You can still do this in an event driven way with a rule though.

  • Setup the Rule Trigger for anytime the audioTrackData attribute changes
  • Drop the HTTP action from your rule
  • Each of the Set Variable actions could parse and read the values from $context.event.value

Thank you for helping me on this Josh! I tried it but it seems that I’m doing something wrong.

Setting a Variable action to read values from

$context.event.value.artist

is giving the variable a null value

The rule logs:

Message Triggered by device event: Speakers audioTrackData is [object Object]

Runtime Data:

[
  {
    "type": "event",
    "subtype": "device",
    "data": {
      "platform": "samsung-smartthings",
      "value": {
        "album": "On How Life Is",
        "albumArtUrl": "",
        "artist": "Macy Gray",
        "mediaSource": "Spotify",
        "title": "I Try"
      },

:thinking:

Here’s an example for you:

Trigger

My Sonos integration with SmartThings was acting up, so I’m testing with Hubitat which has some minor differences. I’m using the attribute trackData from Hubitat, but it’s audioTrackData with SmartThings if I remember correctly.

Action: Parse and Set Variable

In each of the actions, I’m using a Set Variable action and I’m using Expression as the source.

We are able to access the value that triggered the rule using the $context.event.value Context Variable. And since the value is likely a “stringified” version of the JSON object, we can use the parseJson() expression function to get it back into an object format so we can access the property

In the second example with the $OfficeTitle variable, I’m just showing how you can use other expressions to accomplish more advanced logic.

data = parseJson($context.event.value)
isEmpty(data.title) ? data.name : data.title

The first line is parsing the event value and temporarily storing the object as an expression-local variable data.

Then in the second line, we’re using a ternary condition which reads like ifCondition ? then : else and the reason I demonstrated that is SmartThings stores the track title as title whereas Hubitat stores it as name so this particular expression works with either platform. :slight_smile:

I am getting “expression evaluation error”. What am I missing? :thinking:

It looks like SmartThings is actually posting the event across as an actual object whereas Hubitat sends it over as the string format.

Since it appears to be coming across in object format, I would have thought that you could access the property directly like you tried: $context.event.value.artist

You could try explicitly stringifying it then parsing it as a workaround:

parseJson(stringify($context.event.value)).artist

Otherwise I might have to try to get my Sonos-SmartThings integration working again so I can see for myself. :thinking:

Thank you so much for your help Josh! Your suggestion to use stringify and then parse the value worked perfectly. I really appreciate the support and guidance—it saved me a lot of time. You are awesome! :blush:

Thanks for the update!

Context Variable Quirk

I was able to get my Sonos integration working with SmartThings again and I think I see what’s happening.

I think it’s actually just a quirk in how the Expression system handles context variables. Some of the other ‘special’ context variables like event parameters, response data, and event ‘data’ do support nested properties like $context.response.data.someAttribute

The $context.event.value does not directly supported nested properties as historically only text and numeric values were received from the smart home platforms.

Simpler Workaround

As an alternative workaround, you can either assign the $context.event.value to a expression local variable and or just wrap it in parentheses.

data = $context.event.value
data.artist

-or-

($context.event.value).artist

Hi Josh

Thanks to your guidance, I now have everything working perfectly, and I learned a lot in the process. I truly appreciate the effort and support you put into assisting me. You are the best!

One last thing. In another rule for my Speakers, I need to get the value of the current “volume” attribute, but this time I need to run this rule by the press of a Super Tile button. Is there a way to pass the data from Trigger to the Flow section without an Event Trigger by Device → Thing → Attribute → Operator “changes”?

Then I can make a Variable Action to update the variable $VolumeUp from the expression $context.event.value + 1 and then write the new value of this Variable to “Set Volume” and raise the volume by 1% instead of 5%.

It took me two afternoons playing with the expressions and rule triggering options, but I finally found the solution and it’s very simple.

  1. I made a Rule that is triggered when the Volume changes and writes the value of the volume attribute to a variable. The expression that works for this attribute is $context.event.value

  2. Then I made two Rules without any Trigger, that simply read the current value of the variable. One Rule adds 1 to it and the other Rule subtracts 1 from it. Then, with a Device Action at the Flow section, I execute command setVolume to send the new value of the variable to the speakers.

  3. I created a super tile with icons that set to run the rules on tap. It works like a charm!

So now I use a small tile at the size of 1x1 to control my volume at the Home (general) Dashboard and I also have another Dashboard only for Music where I use the awesome Vertical Range Input (Slider/Dimmer) Tile you created for the community. :blush:

Thank you again for your support and all the suggestions. :pray:

1 Like