Are APIs available to Custom App Developers for leveraging Rooms and the Devices therein?

I've been unable to find developer docs for leveraging/extending Hubitat rooms:

Objective

  • access | input a list of existing rooms,
  • access | input devices for a room

There have been no hits yet on my Community post:

I am considering two approaches, neither of which feels right.

  1. Use asynchttpGet() and screen-scrape "http://${location.hub.localIP}/room/list"
  2. Develop an app-specific notion of 'rooms' - i.e., have clients name rooms, identify devices, ...

I’m not a developer but I believe rooms are still in a pretty early phase of development. They exist, but there’s not a whole lot to do with them yet.

So this might be more of a feature request than anything else?

@marktheknife: That's definitely the impression I am getting. To move forward, I may end up creating rooms in an app and cutting back to Hubitat rooms once APIs emerge.

webcore can provide this information in latest release.

See:

That suggests there is an API to get the information, it just isnt public.

Maker API includes the room in the output for a device (I've tested this myself and can see a "room" value come through):

There was talk on a 2 year old topic about a room listing available to Apps, but given the age of the post and the likelihood for change in that time, I would want to get more up-to-date detail, which I don't have. Either way, that is likely not what you are looking for, at least as a first option.

There is also the roomName property discussed here:

From a driver or an app that has access to a device you can get the room ID and name as follows:

device.getRoomId()
device.getRoomName()

From an app you can get the list of rooms as follows:

app.getRooms()

3 Likes

I was hoping that it would be possible for the user to select a room and be presented with a list of devices that are assigned to that room. But it sounds like you already have to be authorized for a device to get the Room property, so not useful in a device picker context.

But useful information all the same and potentially enough to work around the problem in a brute force kind of way.

This works!
Is there a process (user contribution or such) to add a line or two in the app-object doc?

paragraph "Rooms: ${app.getRooms()}"

Yields all the salient info for the rooms.

Example:

Rooms: [[id:1, name:Control, deviceIds:[5536, 3, 5165, 5614, 5615, 5232, 5617, 5618, 5619, 5620, 5621, 5751, 5625, 5689, 5693]], [id:4, name:Den, deviceIds:[5648, 1, 5639, 5671, 5656, 5672, 5673]], [id:9, name:Den Lamp, deviceIds:[5668]], [id:5, name:Entry, deviceIds:[5651, 5645, 5631, 5647]], [id:3, name:Guest, deviceIds:[5682, 5642, 5658, 5627, 5692, 5229]], [id:17, name:Her Closet, deviceIds:[5665, 5690]], [id:16, name:His Closet, deviceIds:[5667, 5691]], [id:14, name:Keypads, deviceIds:[5632, 5637, 5643, 5644, 5646, 5774, 5775, 5776, 5652, 5654, 5657, 5659, 5662, 5679, 5686, 5694, 5695, 5696, 5697, 5698, 5699, 5700, 5701, 5702, 5703, 5704, 5705, 5706, 5707, 5708, 5709, 5710, 5711, 5712, 5713, 5714, 5715, 5716, 5717, 5718, 5719, 5720, 5721, 5722, 5723, 5724, 5725, 5726, 5727, 5728, 5729, 5730, 5731, 5732, 5733, 5734, 5735, 5736, 5737, 5738, 5739, 5740]], [id:10, name:Kitchen, deviceIds:[5670, 5626, 5674]], [id:12, name:Lanai, deviceIds:[5537, 5666, 5653]], [id:15, name:Laundry, deviceIds:[5635, 5630]], [id:18, name:LHS Bath, deviceIds:[5680, 5641, 5678]], [id:21, name:LHS Bedrm, deviceIds:[580, 5231]], [id:7, name:Master, deviceIds:[5650, 5636]], [id:20, name:Master Bath, deviceIds:[5664, 5633, 5660, 5663]], [id:6, name:Office, deviceIds:[5649]], [id:11, name:Pantry, deviceIds:], [id:19, name:RHS Bath, deviceIds:[5634, 5684, 5685, 5661]], [id:8, name:Security, deviceIds:[5744, 5745, 5746, 5683, 5747, 5748, 5749, 5638, 5750, 5687, 5688, 5629]], [id:2, name:Yard, deviceIds:[5681, 5831, 5640, 5628, 5533, 5677, 5534]]]

How do you select rooms in the app? Or does this provide the full list on the hub?

Can you actually do anything with the room and device information? I'd think that you still need to select the devices in the app in order to be able to reference them directly.

I guess this room info might just help you better organize the app config pages, but you'd still have to actually present a device selector in the UI, correct?

At one point I threw together a quick device driver:

2 Likes

Some sample code and output.

//Generic placeholder for test function.
def test(){   
    def roomDeviceIds
    
    myRooms = app.getRooms()
    log.info ("myRooms is: $myRooms")
    
    def roomList = myRooms.collect { it.name }
    log.info ("roomList is: $roomList")
    
    def roomData = myRooms.find { it.name == 'Basement'}
    log.info ("roomData is: $roomData")
    
    if (roomData) {
        roomDeviceIds = roomData.deviceIds
        log.info("Room Device List is: $roomDeviceIds")
    } 
    else {
        log.info("No devices found.")
    }
}

Have not yet figured out how to limit the Input command to this list. Does not seem like it is possible from what I can tell. Only limits seem to be capability and deviceDriver

1 Like

What do you do with those device IDs? You can't just operate on an arbitrary device unless it was selected on an app input page and/or is a child. Just curious what the actual use case is for this info.

1 Like

Good question, I'd like to know that myself. It seems like the use case is probably limited to Maker API because the Device ID is part of the command path, but that is just a guess.

1 Like

How do you select rooms in the app?

Here is a code snippet to selecting rooms.

/*
 * I have not found an `import com.hubitat.app.x for a RoomWrapper
 * or RoomWrapperList type. ArrayList<LinkedHashMap> works for now.
 */
ArrayList<LinkedHashMap> rooms = app.getRooms() 

// Process the results to generate a room picklist.
List<Map<Integer, String>> roomPicklist = rooms.sort{it.name}.collect{[(it.id): it.name]}

input(
  name: 'roomId',
  type: 'enum',
  title: 'Select one room',
  submitOnChange: true,
  required: true,
  multiple: false,
  options: roomPicklist
)

As @garyjmilne notes, the resulting room information is of limited immediate use today.

For "security reasons", Hubitat does not expose the Hub's devices to our custom apps in a convenient way. Our custom apps only gain access to devices via input(...) directives.

Clients - by selecting presented devices - are in affect "authorizing" our custom apps access to a subset of their (private) devices.

Currently, the input(...) facility lacks filtering. There is no way to pass in a closure that narrows the choices presented to a client.

  • A closure could facilitate robust filtering - e.g., narrow the devices presented to a client based on the enclosing room, a substring that occurs in the device's type, etc.

We can ask a client to select ALL of the devices our app might need (irrespective of room). Our application can process the resulting DeviceWrapperList parsing the DeviceWrapper instances using device methods - e.g., getRoomId(), getRoomName().

  • Currently, there is no way for a client to "select all" when using input(...) which is a significant inconvenience if they need to "authorize" a lot of devices.

As @tomw illustrates with his sample code (below), screen-scraping Hubitat's UI works assuming you hold the credentials on the target hub and the screens are stable across releases.

Added this Feature Request

4 Likes