Check if settings contains device

Hi there, I have an app that stores device-specific state information in a HashMap called state.devices.

input name: "valvesToManage", type: "capability.valve", title: "Valves To Manage", multiple: true
...
def update() {
....
    settings.valvesToManage.each{s -> 
        if(state.devices.containsKey(s.id)) {
            state.devices[s.id].name = s.getDisplayName()
        }
        else {
            state.devices.put(s.id, [name: s.getDisplayName()])
        }
    }
}

That all works fine but if I remove a device from the settings.valvesToManage, I have orphaned entries in state.devices. The simple solution is to iterate through state.devices and see if the device exists in settings.valvesToManage. For some reason, I can't get that to work.

I've tried:

    state.devices.each{ o->
        log.debug "checking  ${o.key}"
        if(   ! settings.valvesToManage.contains(o.key){
            log.debug "found orphan: ${o}"
            orphaned.add(o.key)
        }
    }

Any ideas?

I do something similar in an app and here is a post with example code:

Hopefully that gets you going.

If I'm tracking your code correctly, you loaded the settings objects into a deviceList and then checked that deviceList for orphaned entries?

I guess I could do that, it just seems strange that I can't use contains(key) or something similar to access a specific device.

settings.valvesToManage is an array not a map. In your first piece of code you are iterating through the array getting each ID but then in your orphaned code you are expecting it to be a map searching for a key thus it doesn't work. Since you are looping through each of the valvesToManage why not push each ID to an array within that code and then use it after that each loop to remove the orphans like my example:

def update() {
....
    def deviceList = []
    settings.valvesToManage.each{s -> 
        deviceList.push(s.id)
        if(state.devices.containsKey(s.id)) {
            state.devices[s.id].name = s.getDisplayName()
        }
        else {
            state.devices.put(s.id, [name: s.getDisplayName()])
        }
    }
    
    def stateItemKeys = state[devices].keySet()
    for (int v = 0; v < stateItemKeys.size(); v++) {
        def key = stateItemKeys[v]
        if (deviceList.indexOf(key) == -1) {
            state.devices.remove(key)
        }
    }
}

Fair point. I followed your suggestion and it works well. thank you!

1 Like