Cannot get property on null Object

Maybe someone could shed some light on this issue :smile:

multiAttributeTile(name:"power", type:"generic", width:6, height:4) {
		tileAttribute("device.power", key: "PRIMARY_CONTROL") {
  			attributeState "default", label: '${currentValue} W', icon: "${textIconUrl()}", 
                         foregroundColor: "#000000",
			  [value: 1, color: "#00cc00"], //Light Green
            	          [value: 2000, color: "#79b821"], //Darker Green
            	          [value: 3000, color: "#ffa81e"], //Orange
			  [value: 4000, color: "#fb1b42"] //Bright Red

returns this when trying to save in IDE: java.lang.NullPointerException: Cannot get property 'iconUrl' on null object @ line 164

Here is line 164: private def textIconUrl() { def text = "${state.iconUrl}" }

Logging the state shows it is definitely not null: debug textIconUrl: https://(url)/image.png

Try this:
def text
text = “${state.iconUrl}”

Or just this
text = state.iconUrl

I just gave those a whirl with zero effect.

In it’s current form both the ‘state.iconUrl’ and the textIconUrl() have valid data until i try to reference them in the attributeState "default", label: '${currentValue} W', icon: '${textIconUrl()}',

I just tried to replace the " " with ’ ’ and it allowed me to save and publish but the icon is still blank

I believe the metadata part of the code is executed before anything else is available. I think it’s used to create a description of the device/SmartApp for the client to use.

You may notice that the ‘${currentValue} W’ has single quotes around it, this means that it won’t get evaluated at this point but by something later (I suspect the client side does a token replacement). Double quotes in Groove make a GString which are lazily evaluated when they contain a template which is why your code ran initially and gave you the error. Changing to single quotes is now simply setting the value to ‘${textIconUrl()}’ as a raw string which is then given to client which doesn’t know what to do about it.

I am not sure what you want to do is even possible unfortunately.

1 Like

I think it actually needs to be single quotes around it to start with.


Notice anything strange about the label value for state? It appears to be using Groovy’s string interpolation syntax (${}), but with a single quote. In Groovy, String interpolation is only possible for strings defined in double quotes. So, what gives?

When the SmartThings platform executes the tiles() method you have defined, it doesn’t yet know anything about the actual devices. Only later, when the device details screen is rendered in the mobile client, does the platform know information about the specific devices.

So, we use single quotes for the label (${name}) because the platform can then manually substitute the actual value later, when it is available.

Long story short - the above is not a typo. Use single quotes for interpolated string values in the tiles definition.

1 Like

Yay! I was right :smile: Just wish I’d found that link earlier so I wouldn’t have been guessing so much :smile:

1 Like

Did you try just using this?

icon: '${state.iconUrl}',

I’m not convinced that state is given to the client so I doubt it’d know how to evaluate that. Also, I think at this point we’re in the context of the whatever the tile has been assigned to (in this case device.power) so it’s possible that the client would be looking for “device.power.state.iconUrl” :frowning:

That note was just added 2 days ago. :smile:

1 Like

I don’t think you can refer to anything outside of the context of the attribute that’s assigned to the tile (device.power). You’d have to set the tile to use “device.iconUrl” and then have the icon use ‘${currentValue}’… but the issue arises that the label can’t be used to display anything meaningful.

1 Like

Thanks Chris… This is the type of customization options that makes developing for it kinda annoying

1 Like