Maker API Inconsistencies

I'm going an integration with a utility that works across multiple HA platforms, and I've noticed some oddities (IMO) in the Maker API responses.

Different response formats for /devices/all vs /devices/id

The format of the device objects in the devices/all response and individual device responses is different; it would be really helpful if they were the same, and more to the point, it would be really helpful if "all" looked like the individual. The specific differences are that the attributes dictionary in the "all" response seems to have string keys and values, where the attributes in the individual response is an array of objects, one object per attributes.

Example attributes in "all" response for a dimmer:

	"attributes": {
		"level": "50",
		"dataType": "ENUM",
		"values": ["on", "off"],
		"switch": "on"
	},

Oddly, it looks like the "dataType" applies to the switch attribute, and no type for the level attribute -- can't reuse the same dataType key, so it looks like kind of an odd mashup of the two capabilities happened. Doesn't seem right.

In contrast, here's an individual response for the same dimmer:

	"attributes": [{
		"name": "level",
		"currentValue": 50,
		"dataType": "NUMBER"
	}, {
		"name": "switch",
		"currentValue": "on",
		"dataType": "ENUM",
		"values": ["on", "off"]
	}],

This is better. More like what I expected at first.

Different capabilities array structure in /devices/all vs /devices/id

  1. The capabilities list in the all response is a simple array of strings; the capabilities in the individual response is an array that appears to contain a string followed by an object (that is, the capability name is element 0 of the array, and then an object follows it in element 1, followed by another string, ...). I'm a bit puzzled by this. I think it would be more useful it it was either an array of objects, or simply the array of strings as presented in the "all" response.

Example "all" response capabilities for the same dimmer device used above:

	"capabilities": ["Switch", "SwitchLevel", "Refresh"],

And here's the individual response format:

	"capabilities": ["Switch", {
		"attributes": [{
			"name": "switch",
			"dataType": null
		}]
	}, "SwitchLevel", {
		"attributes": [{
			"name": "level",
			"dataType": null
		}]
	}, "Refresh"],

I like that it gives the attributes for the capabilities, I just find it odd that it gives the description object as a separate array element from the capability name, rather than making a structure that looks more like this:

	"capabilities": [{
			"Switch": {
				"attributes": [{
					"name": "switch",
					"dataType": null
				}]
			}
		},
		{
			"SwitchLevel": {
				"attributes": [{
					"name": "level",
					"dataType": null
				}]
			}
		},
		{
			"Refresh": {}
		}
	]

I've standardized on the individual device response format for my work, but it means I can't get all the devices in one response without writing completely different parsing and handling for that form; instead I query for the list without detail, and then query each device individually, so when the system has a large number of devices, the startup overhead of the initial queries to get the status of every device individually is unpleasantly high.

Never use devices/all, do devices/*

devices/all doesn't return all data, and sometimes mangles the json formatting. It's been reported multiple times to Hubitat. :man_shrugging: Avoid it.

devices/* is also MUCH faster than /all.

3 Likes

Thank you! Did I miss that in the docs or is it a recent addition?

attributes definitely looks better... capabilities still odd, but if as long as that's a stable format, it's got everything needed.

I don't know if it is documented - it was NOT when I found out about it. Once I knew about it, I never went back and looked...

Just noticed that /devices/* seems to omit the type key present in the other formats. I guess you can't have everything, as they say. At least I can work around that more easily.