Issue using variables

hi guys new to groovy and coding in general, ive stuck some code together which you can see in the following link

the code is obliviously a mess and was to test some functionality out with my sony TV however, I got all the functions working seperatley and now im trying to slim the code down and take out any duplication and also alow the app to enter some of the variables. im working through it now trying to clean it up and ive hit a snag with ‘def’

it appears that something ive Defined in the beginning of the script, cant be called from within another def which is causing my script to run with null values

an example

line 96, this def tv_ip joins all the seperate parts of an IP address together and when i log.debug ("${tv_ip}") i get what i expect in this instance 192.168.0.12

I then call tv_ip again on line 133 but the value is null

can anyone explain to me what im doing wrong? i think its because im using def but i cant figure it out (iff i uncomment line 129 this starts working as normal, but i want this value to be set globally

  1. There is no way to create your own global variables in a SmartThings SmartApp or DTH.
  2. You also cannot put any code outside the meta{} section or a method definition.
  3. You can only “def” methods (which could just return a constant…),
  4. You can “def” variable within a method, but their scope is constrained to the method.
  5. So … Use the one “global persistent map” provided to SmartApp instances…

state[] | atomicState[]

##docs
http://docs.smartthings.com/en/latest/smartapp-developers-guide/state.html

2 Likes

Hmm an interesting read, so how would device handlers and developers normally handle something like this, I assume to get the functionality I need I will need to store the IP address and other details in state reading that page it seems this is how it works. Does that sound reasonable or should I be structuring the code in a different way?

Both Device Type Handlers and SmartApps also have “Preference” inputs which are stored in the read-only map settings[] (it can only be written by the inputs), so if the IP address is something user inputs and might change, that’s a more typical option than state. But both are useful.

Your best starting point is to look through lots of example code including the Public SmartThings Community GitHub repo.

ok ive not had chance to look at to many other device handlers all thought i did spend most of last night looking through threads.

Ive been trying to follow the documentation on state and settings but ive hit the wall again

preferences {
	section("IP Address"){
		input "ipadd1", type: "number", range: "0..254", required: false, title: "Ip address part 1"
		input "ipadd2", type: "number", range: "0..254", required: false, title: "Ip address part 2"
		input "ipadd3", type: "number", range: "0..254", required: false, title: "Ip address part 3"
		input "ipadd4", type: "number", range: "0..254", required: false, title: "Ip address part 4"
		input "tv_psk", type: "text", defaultValue: "1111", title: "Passphrase", description: "Enter passphrase", required: false
}		
}

log.debug(" input test ${ipadd1} ${ipadd2} ${ipadd3} ${ipadd4}")
//log.debug("${settings.ipAdd1} ${settings.ipAdd2} ${settings.ipAdd3} ${settings.ipAdd4}")
log.debug("input test 2 $ipadd1 $ipadd2 $ipadd3 $ipadd4")
//log.debug("$settings.ipAdd1 $settings.ipAdd2 $settings.ipAdd3 $settings.ipAdd4")


def tv_ip = "${ipadd1}" + "." + "${ipadd2}" + "." + "${ipadd3}" + "." + "${ipadd4}"
	state.tv_ip = tv_ip

	def port = "80"

I can get the values from the app into ipadd1, ipadd2 and so on that works fine

and previously in the code i could get a valid IP address string out of this

def tv_ip = ("${ipadd1}" + "." + "${ipadd2}" + "." + "${ipadd3}" + "." + "${ipadd4}")

but now ive introduced state i get an error as follows when trying to save the code

def tv_ip = "${ipadd1}" + "." + "${ipadd2}" + "." + "${ipadd3}" + "." + "${ipadd4}"
	state.tv_ip = tv_ip //line 95

java.lang.NullPointerException: Cannot set property ‘tv_ip’ on null object @ line 95

this also doesnt work if i do

state.tv_ip = ("${ipadd1}" + "." + "${ipadd2}" + "." + "${ipadd3}" + "." + "${ipadd4}")

can anyone see what im missing?

hmm i may have figured out what you mean now by

so my next question is, i need to run some code the above code and some other code, once or not very often in order to generate some values for my state variables

for instance i want to create a variable that takes the data entered in the preferences does a few simple calculations and stores them, in state. can i call a method when the settings page is changed or saved?

hmm look slike i should do some more reading into the following. Looks like updated is what im after here, but im guessing the others are usefull at other times

def installed() {
}

def updated() {
}

def initialize() {
}
1 Like

Look up the documentation on the standard methods: installed() and updated() please.

(And please RTFM. :smile:edit: Which is seems you are doing now, since you discovered the above two methods before I posted this!).