supportedThermostatModes isn't supposed to be JSON_OBJECT?

Can someone shed some light on what exactly is expected with regards to the Capability and MakerAPI around the output of supportedThermostatModes (and all the other supportedXYZ attributes) when it is marked as being a JSON Object?

Correctly formatted JSON would be ["heat", "cool", "auto", "off"]

attribute "supportedThermostatModes", "JSON_OBJECT"

But the below code actually ends up sending [heat, cool, auto, off]

  sendEvent(name: "supportedThermostatModes", value: ["heat", "cool", "auto", "off"])

And when I check Thermostat Controller, it expects the attributes to be sent like this too.. [heat, cool, auto, off] ... which I would consider to be incorrect and not valid JSON.

So what's the correct and valid output ?? (other than whatever works) :slight_smile:

This code will produce valid JSON from a List
groovy.json.JsonOutput.toJson(["heat", "cool", "auto", "off"])

Not sure about Maker API, which is kind of a major part of your question, I now realise.... but here's an example of my adjustment of the modes for my Mitsubishi driver:

def adjustThermostatModes(pCanHeat,pCanCool,pCanDry, pCanAuto) {


    parent.debugLog("adjustThermostatModes: Adjusting Thermostat Modes...")

    def thermostatModes = []

    parent.debugLog("adjustThermostatModes: CanHeat = ${pCanHeat}, CanCool = ${pCanCool}, CanDry = ${pCanDry}, CanAuto = ${pCanAuto}")


    if(pCanHeat == "true" || pCanHeat == "1") { thermostatModes.add('heat') }

    if(pCanCool == "true" || pCanCool == "1") { thermostatModes.add('cool') }

    if(pCanDry  == "true" || pCanDry  == "1") { thermostatModes.add('dry')  }

    if(pCanAuto == "true" || pCanAuto == "1") { thermostatModes.add('auto') }





    parent.debugLog("adjustThermostatModes: thermostatModes detected are ${thermostatModes}")

    sendEvent(name: 'supportedThermostatModes', value: thermostatModes)



This may also not help with your original question, at in terms of the "what works" clause, but in the end it may be what the devices expect, rightly or wrongly....

This is the closest I ever got an answer to on a similar question I asked a while back, in case it's a helpful reference. :smiley:

1 Like

maybe @bcopeland can chime in. He's the thermostat guru

There is a problem with this that we are aware of, and intend to fix in the next release. What is supposed to be returned should be a JSON Object. But what is being returned is an improperly constructed String that sort of looks like a JSON Object, but isn't.

The fix for this is for us to correct every thermostat driver. That in turn means that every app that uses this attribute (and supportedThermostatFanModes) has to be updated to deal with the fix. Right now, all of these apps are manually parsing the string value into a list. They should be able to use parseJson() instead. We plan for this fix to be in the next release (2.3.3).

In the meantime, you can take the returned string apart by removing the brackets, and doing tokenize(",") to get a list of Strings.


Will you please document the correct data format for the attribute somewhere so that community driver developers can also get it "right?"

As described above, the individual values should be in quotes (but are not):


The corrected code looks like this:

setSupportedThermostatModes(JsonOutput.toJson(["auto", "cool", "emergency heat", "heat", "off"]))
def setSupportedThermostatModes(modes) {
    sendEvent(name: "supportedThermostatModes", value: modes)

Using this code I get this error:

java.lang.NullPointerException: Cannot invoke method toJson() on null object on line 155 (method configure)

setSupportedThermostatModes(groovy.json.JsonOutput.toJson(["auto", "cool", "emergency heat", "heat", "off"]))


that did it...oddly it's wrong in the virtual driver example....

I'll bet import groovy.json.JsonOutput appears somewhere in the example you mentioned.


I'll bet you're right! Thanks!

1 Like