Seeking clarification on preferences{} and actual device params


(George) #1

Hi. Please confirm if my understanding of this is correct:

Using preferences{} seems like the proper way to alter device configuration parameters. I’d like to clarify – preferences{} values are stored and populated independently of what the actual parameters are on the device. Let’s say, a user sets param 6 to [0] using preferences{} in the UI. Subsequently, param 6 is set to [1] without user intervention by either the DH or a smartapp. When the user goes into preferences{}, he will see [0] as the current value, even though the device now has [1] in param 6. Is this correct?

Could you point me to an example (if you’re aware of one) where configure() (I assume that’s the way it would be done, if there’s a different way, would very much appreciate the info) is used to retrieve current params from the device and to populate the settings.paramX so that preferences{} UI reflects the actual current device param configuration and not the last saved (by user) preferences{} values.

Thank you!


How to read parameters initially
Is it possible to reset preferences from a tile action method?
(Mike Maxwell) #2

Unfortunately preferences, like your ir remote are a one way street, they can only be set via the Mobil app. So they won’t be synced from the device if they aren’t set via the device type preferences. Major bummer, I know.


(codersaur) #3

Why is this marked as solved, when it clearly isn’t?!?

I’m updating a device driver for the Fibaro Dimmer 2, which has the capability to change it’s own parameters (via Auto-calibration feature). I want the settings shown in the SmartThings device to be able to updated with the real device parameters when this happens.

I have an event handler for receiving the configuration reports, but if I try the following code to update the device preferences, it fails with a groovy.lang.ReadOnlyPropertyException:

device.preferences.param19.value = 14

If device.preferences are currently read-only then we need to make a feature request to allow editing from code, as this would be a really useful feature.

@Aaron, can we get this as a feature request?


(ActionTiles.com co-founder Terry @ActionTiles; GitHub: @cosmicpuppy) #4

Device (and SmartApp) Preferences are Read-Only for security reasnons.

The customer sets Preferences (and authorizes devices, etc.), and code should not be allowed to change those preferences!!!


(codersaur) #5

I’m not sure I agree with this. Regardless… @tgauchat how would you then suggest to solve the problem where device parameters (specified in the settings UI and sent to the device) subsequently become out-of-sync with the the physical device (e.g. the Fibaro Dimmer runs its auto-calibrate feature which changes various parameters)? At the moment, there appears to be no mechanism to show users the real parameter values in their devices via the UI.


(ActionTiles.com co-founder Terry @ActionTiles; GitHub: @cosmicpuppy) #6

Yah… Hope you realize that I was being pedantic. The architecture makes sense, but that’s no reason for SmartThings not to come up with a flexible solution.

So…

  1. At the moment, the possibile option is to have use separate “Value Tiles” which you can update, rather than or in addition control tiles or input fields. It’s not uncommon to see up and down “^v” Tiles with the value in the middle. Yech. But it works.

  2. Wait for the release of “HTML” tiles/pages which will be integrated with SmartApps and DTHs. They were demonstrated months ago at the Samsung Developers Conference; but are being released on SmartThings’s timeline.


(codersaur) #7

Well finally, I can say Mike is wrong! :stuck_out_tongue: It appears we can now use:

app.updateSetting(inputName, [type: type, value: value]) 
app.updateSetting(inputName, value)
// or for DTHs:
device.updateSetting(inputName, [type: type, value: value]) 
device.updateSetting(inputName, value)

(Mike Maxwell) #8

updateSetting must be a new method, I’m seldom wrong, at least in my own mind…
where did you find this BTW?


(codersaur) #9

github.

I’ve realised it’s not very consistent with the other methods for accessing settings, e.g.:

Reading settings values:

def p = setting.settingName
// Or:
def p = device.getPreferenceValue("settingName")

Updating settings values:

device.updateSetting(settingName, [type: type, value: value]) 

Reading settings meta-data via preferences:

preferences?.sections.each { section ->
    section.input.each { input ->
    	log.debug "$device.displayName: Found input: ${input.inspect()}"
    	log.debug "$device.displayName: Input value: ${input.value}" // Returns null.
        if (input.defaultValue != null) { // this returns true if default value is (bool)false.
        	log.debug "$device.displayName: Found defaultValue for: ${input.name}: ${input.defaultValue}"
        }
    }
}

All a bit of a mess really…

You would think we could have a standard name for these things too. I never know whether to use “preferences”, “settings”, or “inputs”!! :imp:


(Mike Maxwell) #10

I can confirm the short version works in a dth, however there’s quite a bit of funk to it
It will not update a setting unless it’s already been set (once), after that it’s fine.
The preferences settings in the UI aren’t updated to match those set in code…
The long version, just sets the pref to null, most awesomely, this is reflected in the ui…

/*
 
*/
metadata {
	
    definition (name: "updateSettingDTH", namespace: "mmaxwell", author: "mike maxwell") {
		capability "Switch"
 	}
    preferences {
       	input name: "enum1", type: "enum", title: "test enum 1", description: "enum1", required: true, options:["1","0"]
        input name: "bool1", type: "bool", title: "test bool 1", description: "bool1", required: true
    }
	tiles {
		standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
			state "off", label: '${currentValue}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
			state "on", label: '${currentValue}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#79b821"
		}

        main "switch"
		details(["switch"])
	}
}


def on() {
	sendEvent(name: "switch", value: "on")
    //device.updateSetting("enum1", [type: "enum", value: "1"]) //sets input to null
    //device.updateSetting("bool1", [type: "bool", value: true]) //sets input to null

	device.updateSetting("enum1","1")  //works
    device.updateSetting("bool1", true) //works
    
    log.debug "values after ON, enum1:${enum1}, bool1:${bool1}"
}

def off() {
	sendEvent(name: "switch", value: "off")
    //device.updateSetting("enum1", [type: "enum", value: "0"]) //sets input to null
    //device.updateSetting("bool1", [type: "bool", value: false]) //sets input to null
    
    
    device.updateSetting("enum1","0")  //works
    device.updateSetting("bool1", false)  //works
    
    log.debug "values after OFF, enum1:${enum1}, bool1:${bool1}"
}

def updated(){
	log.debug "values after pref set, enum1:${enum1}, bool1:${bool1}"
}

I had assumed that the long version was a map parameter element, maybe device.updateSetting(“bool1”, type: “bool”, value: true) would work, if someone else wants to test this…


(codersaur) #11

This doesn’t match my quick testing today:

If a setting already has a non-null value then you can change it with device.updateSetting(inputName, value) and it will update in the UI (at least on iPhone it will). You can also set it to null.

However, if the setting is currently not set (i.e. settings.inputName == null) then you cannot give it a value using device.updateSetting(inputName, value).

However, I only tested with the short version and using a “number” type input.

Possibly the reason why this is not a documented/supported function yet is that it’s still a work in progress…?


(Mike Maxwell) #12

right, no initial setting, and you can’t set it via code.
likely the android mobile app is at fault for not updating the setting when it does change…
In any event, broken as it is currently, it’s a step in the right direction and better than nothing…