If statement inside metadata

Ok for command I did

    if (getDataValue("rgbwplus") == true)  {
    command "setEffect", [[name:"Effect to use (0=OFF)", type: "NUMBER", description: "Effect to use (0=OFF)", constraints: ["0","1","2","3","4","5","6",]]]
    }
    else if (getDataValue("rgbwplus") == false)  {
    command "setEffect", [[name:"Effect to use (0=OFF)", type: "NUMBER", description: "Effect to use (0=OFF)", constraints: ["0","1","2","3"]]]
    }

In updated() I added

if (rgbwplus == true) { updateDataValue("rgbwplus", true) }
else {updateDataValue("rgbwplus", false) }

Not working so I am missing something....

let me play with it for a while. See what I get.

Dave

1 Like

Thanks... It's so close I can taste it.... I have been working on it for the last 2 hours and it has to be a small detail I am missing. The logic is right....

I Failed. Apparently, the system wants static data in the definition section but will take dynamic data in the preferences section. Error in other code is the data in updateDataValue must be a string.
Dave
Code I used.

metadata {
	definition (name: "ZZZZZ",
    			namespace: "davegut",
                author: "Dave Gutheinz",
				importUrl: ""
			   ) {
		log.info "definition: rgbwType = ${getDataValue("rgbwType")}"
		if (getDataValue("rgbwType") == "rgbwPlus") {
	    	command "setEffectPlus", [[name:"Effect to use (0=OFF)", type: "NUMBER", description: "Effect to use (0=OFF)", constraints: ["0","1","2","3","4","5","6",]]]
		} else {
			command "setEffect2", [[name:"Effect to use (0=OFF)", type: "NUMBER", description: "Effect to use (0=OFF)", constraints: ["0","1","2","3"]]]
		}
	}
    preferences {
		input name: "rgbw_Type", type: "enum", title: "What RGBW device ?", options: ["rgbwPlus", "rgbw2"], defaultValue: "rgbwPlus"
	}
}
def installed() {
	updated()
}
def updated() {
	updateDataValue("rgbwType", rgbw_Type)
	log.info "updated: rgbwType = ${getDataValue("rgbwType")}"
}
def setEffect(effect) {
	log.info "Made it.  effect = ${effect}"
}

Can I see how you are doing it in your code ? Maybe I can adapt it somehow.

I wonder if you can ask for input after you create the device and go to it to set that variable ? You can with apps...

I am trying something else this AM.

How the code above should work:
Installation:

  • program runs method install()
  • the device screen is created using the metadata/preferences. While updating,
    a. the program has the data element "rgbwType"is logged so I can verify it is correct.
    b. It does an if on the data element "rgbwType" and should cause the correct command to display.
  • method updated() is executed.
    a. the data element "rgbwType" is set to the selected preference.
    b. as a test, I display that value in the log.

Save Preferences:

  • method updated() changes the data element "rgbwType" to the selected preference
  • the devices page is generated again.

Again, working this AM. What I am seeing says there are alternatives:
You apparently have two types of lights. Are you installing using an application or a manual installation?
If using an application, can the application determine the device type? If so, it could use this data. More on this if my test succeeds.

Dave

1 Like

The code below works. It is sub-optimal to your program intent. It works well if the device type (rgbwPlus vice rgbw2) will not change after installation. Ways to use:
a. Create two driver files from the same code, one with devType = rgbwPlus, on the other way. This is recommended. Then your user can have both types involved, just two separate drivers.
b. Instruct your user to change the mark-out above.

Rules for information in Metadata Definitions section:
a. Must be wholly internal to the driver and can not rely on any device data.
b. Must be static.

Dave

//	If the device type is rgbwPlus, the file is already set up.  Otherwise,
//	remove the slashes from the line 'devType = "rgbw2"' to set the device to rgbw2.
	def devType = "rgbwPlus"
//	devType = "rgbw2"
metadata {
	definition (name: "ZZZZZ",
    			namespace: "davegut",
                author: "Dave Gutheinz",
				importUrl: ""
			   ) {
		if (devType == "rgbwPlus") {
	    	command "setEffectPlus", [[name:"Effect to use (0=OFF)", type: "NUMBER", description: "Effect to use (0=OFF)", constraints: ["0","1","2","3","4","5","6",]]]
		} else {
			command "setEffect2", [[name:"Effect to use (0=OFF)", type: "NUMBER", description: "Effect to use (0=OFF)", constraints: ["0","1","2","3"]]]
		}
	}
}
def installed() {
	updated()
}
def updated() {
}
def setEffect(effect) {
	log.info "Made it.  effect = ${effect}"
}
1 Like

Personally, I would just create and maintain the two separate drivers. Asking users to hand edit code seems a little complicated, especially since the user would actually need to also rename the driver to avoid a conflict. What if the user has both types of lights connected to the same hub?

2 Likes

Would need two drivers, one for each. I used to do the same with the TP-Link Integration. I had three development files (plugs, bulbs, energy monitor plugs), then created 8 distribution files. Simplified maintenance.

Thanks, this was a fun diversion.
Dave

1 Like

Dan these devices are non zwave/zigbee so they use either http api or MQTT. The user can install the driver more then once so having both devices wouldn't matter.

All I am trying to do is avoid having to maintain 2 drivers that are only different by 3 light effects.

I appreciate every minute you spent helping me on this. I am going to look at both options.... 2 drivers with just 1 change or simply coding for each one separately.

But the more I think about it....

def devType = "rgbwPlus"
//devType = "rgbw2"

The more I like this idea as all I have to change is the devType and I still can keep all the code in each one.

I understand. :wink:

You also have to change the following driver name section to prevent too drivers with the exact same name.

metadata {
	definition (name: "ZZZZZ",
    			namespace: "davegut",
                author: "Dave Gutheinz",
				importUrl: ""
			   ) {
1 Like

Like that...

1 Like

Yes, that will work.

Again I want to say thank you for all your help. I have modified my code and it works perfectly !!

2 Likes

Sorry to revive this thread that has "solution" ticked, but I have some follow up questions on using conditionals in the metadata {} and preferences{} sections.

In my case, I'm trying to hide/reveal preferences.

I understand that using a data value with a conditional in metadata {} doesn't work, but in my "experiments" I've found it's possible to call getDataValue() in preferences{} on an undefined value which can later be defined in configure() and/or updated().

So, I am wondering if anyone knows where to find documentation on the use/pros & cons/limitations of custom device data values.

As of writing this post today, there's no official Hubitat documentation on updateDataValue() or getDataValue().

@codahq also recently asked about the use of data values (versus the use of state variables), but that remains unanswered.

Any help pointing to a source of information would be greatly appreciated!

It is unfair to say no documentation. It is currently a shell of what may eventually be included.
"Device Object - Hubitat Documentation"
That being said:

Data values are in the Device object. The general format is:
void updateDataValue(String name, String value)
String getDataValue(String name)
example a data value deviceIP

updateDataValue("deviceIP", "192.168.1.1")
getDataValue("deviceIP")

Note that the data values must be a string~!!!!!

Format is
updateDataValue("name of data value", "value of data value").

2 Likes

I don't know about the performance aspects of using data versus state but I updated that other thread with my findings over the last couple months of writing drivers. It's just my opinion/perspective and not backed up by anybody from Hubitat but I like it at least organizationally.

How you do it really does not kill or make a system better. I use the paradigm:

  • Data is core information for the device that is needed for it to function. It is more persistent. Therefore, changing may not be as persistent. Examples I use are IP Address, device-specific parameters (such as video inputs), device-specific command preambles, etc.)
  • State is data related to the operation of the functions of the device. Aside from attributes, examples may include preset channel data, start-of-day data, last setting for use in powering back on.

But it does not matter. Do what is most convenient. Only major difference is data can officially only be strings, so do not store arrays in data - it is easier to handle in states.

1 Like