Struggling with defining/accessing "class" variables

Maybe a bad title--I don't really know Groovy, except as it is similar to C++ and scripting languages that support OO constructs.

I have a data structures that I'd like multiple methods in a device driver to access. For example:

def mediaInputs = 
[
    // This map is keyed by the device name--this must be an enry in the lirc server's conf file /etc/lircd/lirc.conf
    // The value's correspond to remote keys that control which input is selected on that device
    
    "STR-DE985": [
        valid_inputs:["MD/DAT","TV/SAT","VIDEO1/AUX","VIDEO_2","VIDEO_3"],
        streaming_input:"VIDEO1/AUX",
        satellite_input: "VIDEO_2"
        ],
    "panny": [ 
        valid_inputs:["HDMI_1", "HDMI_2", "HDMI_3", "VIDEO_1", "VIDEO_2", "VIDEO_3", "VIDEO_4"],
        streaming_input:"VIDEO1/AUX",
        satellite_input: "VIDEO_2"
        ],
    "RC-R0900": [
        valid_inputs:["VIDEO1", "VIDEO2","VIDEO3","TAPE_1", "TAPE_2"],
        streaming_input:"",
        satellite_input: ""
        ]
] 

But, I can demonstrate my ignorance more simply:

def myVar = "hello"

How do I access myVar in driver method?

I've tried everything that's commented in this method:

def logConfig()
{
    //key = device.getName()
    //log.info $myVar       nothing prints 
    //log.info "$myVar"    "null" is printed
    // log.info "${myVar}   nothing prints
    //log.info this.myVar     nothing prints
    // log.info ${this}.myVar  2021-05-30 10:05:05.081 am errororg.codehaus.groovy.runtime.InvokerInvocationException: groovy.lang.MissingMethodException: No signature of method: user_driver_Flying_Nerd_IR_Control_503.$() is applicable for argument types: (user_driver_Flying_Nerd_IR_Control_503$_logConfig_closure3) values: [user_driver_Flying_Nerd_IR_Control_503$_logConfig_closure3@163c267]
    //log.info this.$myvar     nothingPrints
}

So, what is the correct syntax to use in a driver method to access a variable like myVar (or, mediaInputs)?

You’re overlooking scope, i.e. defining the variable outside of the method attempting to use it.

Yes, that's what I want to do. I want more than one method to access the data. That's what "class" variables are in C++

How do I do that?

Saying a different way, how to define a variable that can be accessed by more than one method in the driver? Don't want it exposed as an attribute.

Or, "static" variable is another name. Global to all instances of the class. Every object (device in Hubitat) can access the data.

It’s a bit of a hack (at least the way I think of it) but in a device driver if I define:

static String version()	{  return '0.1.0'  }

And then later:

log.info “${version()}”

In an app you may be able to use:

@field static String version = ‘0.1.0’
…
log.info “$version”

…and you’re making me use brain cells that have been dormant for a long time,

1 Like

Sure, a method (doesn't need to be static) that returns the data. That should work fine and makes sense. Thanks.

But, so I understand, I'm thinking static data members are not allowed?

"a bit of a hack"

How would you advise encapsulating data structures like this? Only the device driver code needs the map and there's no need to expose the map for an app or device configuration.

I’ve created them, but never seem to be able to use them the way I think I should be able to; but a method can return a map, or array just as easy as a string.

In this case (as @thebearmay pointed out) there's no real need to have the map accessed by multiple methods. Instead, I could have the map defined inside a method that returns a string based on inputs that can be used as keys inside the map.

Right now, it's more about learning Hubitat driver coding practice than "getting it done".

I've looked at a lot of threads and can't find one example where data defined like

myvar

or

mediaInputs

is accessed in a method.

So, I conclude even if it can be done, it's not good practice to do it that way.

Thanks!

Groovy supports static fields. This should do what you're looking for:

import groovy.transform.Field
...

@Field static String myVar= "Hello"
@Field static String PowerOn = "PowerOn"
@Field static String PowerOff= "PowerOff"
...

@Field static Map zone1CmdMap = [PowerOn:"PWR01", PowerOff:"PWR00", PowerQuery:"PWRQSTN", MuteOn:"AMT01", MuteOff:"AMT00", MuteToggle:"AMTTG", MuteQuery:"AMTQSTN", VolumeSet:"MVL", VolumeUp:"MVLUP", VolumeDown:"MVLDOWN", VolumeUp1:"MVLUP1", VolumeDown1:"MVLDOWN1", VolumeQuery:"MVLQSTN", InputSet:"SLI", InputUp:"SLIUP", InputDown:"SLIDOWN", InputQuery:"SLIQSTN"]

String offCmd = zone1CmdMap[PowerOff]
2 Likes

Or you store it as state
state.YourVarName ==

1 Like

That's the part I missed...

@SteveV Thanks, good to know