How Do I Set The Parent Device Of A Device?
Hello, I hope someone can assist with the following. I am using Device Component Mapping to create a hierarchical/tree structure of devices, but SL seems to assign the Parent Device attribute randomly for each device created, and I need to be able to set the Parent Device correctly, so that the hierarchical structure is correct.
I have data that contain a set of locations that correspond to the tree structure. The structure has this concept: One Country -> Many Cities -> Many Buildings -> Many Rooms. Each data record has an id, a name, a parent id and a type. The data is split into cities, buildings and rooms. For example, a city record might be as follows: id: CITYPARIS, name: Paris, parent id: CTRYFRANCE, type: city. A building record might be as follows: id: BLDGMONTPARNASSE, name: Tour Montparnasse, parent id: CITYPARIS, type: building. And to complete the picture, a room record might be as follows: id: ROOMMEETING1, name: Meeting Room 1, parent id: BLDGMONTPARNASSE, type: room.
When I create one of the 'tree' levels of devices (it could be city, or building, or room), in my Dynamic Application, the code snippet extracts cached data where the type is 'city', then passes the extracted data to the result handler, which populates the four collection fields: id, name, parent_id, type. The id field is set to be the Unique Identifier, the name field is set to be the Device Name, and the type field is set to be Class Identifier 1 (I've created device classes for each tree level, allows me to have funky icons to distinguish the devices visually). The DA then creates devices for each record found, and I see them appearing on the Device Manager screen. However, when I examine each device, the Parent Device that is set seems to be random. For example, three city devices created (Paris, Nantes, Poitiers) all were assigned a Parent Device of 'Paris', the name of one of the devices created, instead of using their own parent_id values.
Is there a way to tell SL what the Parent Device for each device record should be, perhaps in the snippet or somewhere else? Can I use one of the field values extracted from the cached data (ideally, my parent_id) as the value for the Parent Device field?
This is my first post here, so apologies if this is in the wrong place!
When you create an app with Dynamic Component Mapping checked, that causes children to be created. That is when the parent device is assigned. To create a device, you must set three fields: name, unique_id, and distinguished_name. The unique_id field is how the system knows that the component is unique within a DCM tree.
If you have duplicates of that field, the system will see it as though the same device is being discovered by different parents. A device can only have one parent which means that the system interprets the second device discovery with the same UID as the device being moved from one parent to the other.
Reading through the PDF that you shared, it sounds like you're doing discovery from the bottom to the top. In our system, you must do discovery from top to bottom. So you would have apps setup like this:
Country Discovery (this creates your root devices)
-> Aligns State Discovery to children
-> Probably aligns a configuration app with details on the country
State Discovery
-> Aligns city discovery to children
-> Probably aligns a configuration app with details on the state
City Discovery
-> Aligns building discovery to children
-> Probably aligns a configuration app with details on the city
Building Discovery
-> Aligns collection apps to children to collect performance/config data
If you want to have an app that goes down to the room level, you keep following that pattern. The data you're getting from the API is oriented around locations. When processing it for use, there are a couple of ways that you could prepare it. One would be to take all of the location data and sort it by its level in the hierarchy. Then you can build a tree in memory that matches the correct order, top to bottom. Each discovery app would then look at its part of the tree to find its children and then build the next layer.
The other way to do it would be to get all of the data in a big list and then when creating the app at each level, you go through each location record and let through the ones that have the current device listed as a parent. For example, you would align country discovery to a reoot device. At the country level, you would output all countries that you find. At the state level, you would look at which country your device represents and then you would output all of the states with that as its parent. For each level below that, you would do the same thing.Looking at your code, you are discovering all devices for each parent. That's causing it them to move randomly between devices since whichever device runs that app last gets that child device. In your code, you're setting a value called PID and returning it to the platform. Rather than return it to the platform, check to see if the parent ID equals the UID of the current device (self.unique_id is, I believe the variable name). If it does, collect it, if not, don't include that device in the list.
Taking a look at how you're processing the data, this would work really well as a snippet framework app. You would have either your requester step get the data from the API and then parse and process it. You can filter out values based on the unique_id using the jmespath parser and variable substitution. This will help future-proof your apps since it'll be using our official framework and will be able to take advantage of all of the logging and performance work that we do for the snippet framework.