Multi threading in Script

Hello There,

I have the application where user presses button (Multiple buttons for different directory) and the timer function will be called. When the timer is complete, another function will be called and it will look for the file on directory. If the file exists, it will grab the information otherwise it will call the timer function again.
Now, the different button will look for the different file, however, the button could be pressed simultaneously. I am afraid that if the function is called and the timer is running than calling the same function again will make it complicated.
I tried looking for multi threading but since I am still a beginner, i couldn’t understand.
The Script in Script Library [Project] -

import threading
from threading import Timer
import os

class PullingData():
	
	Busy_flag = 0
	
	def timerFunc(Machine):
		
		t1 = Timer(5.0, ReadFile,[Machine]).start()
	
	def ReadFile(MachineNum):

		if str(MachineNum) == "MDR1" & Busy_flag == 0:
			contents = "C:\\Users\\kshah2\\Desktop\\file.asc"
			if system.file.fileExists(contents):
				File = system.file.readFileAsString(contents)
				window = system.gui.getWindow('carlos') 	
	 			window.getRootContainer().getComponent("Text Area").text = File
	   			Busy_flag = 0
			else:
				timerFunc(MachineNum)
				Busy_flag = 1
		
		elif str(MachineNum) == "MDR2" & Busy_flag == 0:
			contents = "C:\\Users\\kshah2\\Desktop\\file1.asc"
			if system.file.fileExists(contents):
				File = system.file.readFileAsString(contents)
				window = system.gui.getWindow('carlos') 	
				window.getRootContainer().getComponent("Text Area").text = File
		  		Busy_flag = 0
			else:
				timerFunc(MachineNum)
				Busy_flag = 1
		else:
			contents = "C:\\Users\\kshah2\\Desktop\\file2.asc"
			if system.file.fileExists(contents):
				File = system.file.readFileAsString(contents)
				window = system.gui.getWindow('carlos') 	
		 		window.getRootContainer().getComponent("Text Area").text = File
		 		Busy_flag = 0
			else:
				timerFunc(MachineNum)
				Busy_flag = 1

Script in Button I am calling with -

Button 1 - 
Name = project.Reading_File.PullingData()
setup = Name.timerFunc("MDR1")

Button 2 - 
Name = project.Reading_File.PullingData()
setup = Name.timerFunc("MDR2")

Error I am getting -

Traceback (most recent call last):

  File "<event:mouseClicked>", line 2, in <module>

TypeError: timerFunc() takes exactly 1 argument (2 given)



Ignition v7.8.5 (b2016120813)
Java: Oracle Corporation 1.8.0_131

Any comment is appreciated.
thank you so much

Hello,

The error about the timerFunc taking 1 argument is due to leaving out the self argument of the function. In order to call timerFunc from an instance of the PullingData class as you are doing, you simply need to change the function definition to include self:

def timerFunc(self, Machine):

to define a method in Python you use the following syntax.

def methode_name(self, [args]):

in your script, the self-argument is "Machine". Because you can name it in python the way you like, the behavior of the functions does not expect, an argument.

So your method definitions should be: def timerFunc(self, Machine):

I have not analyzed the code so I do not know if the code works. But this is the cause of the error

thank you guys…
I implemented a program but now there is no results or error at all even nothing in console.
Code -

import time
import threading
from threading import Timer
import os

class PullingData():

	def __init__(self, Machine):
		self.Machine = Machine
		Busy_flag = 0
		return self.timerFunc()
		
							
	def timerFunc(self):			
		t1 = Timer(5.0, self.__ReadFile__)
		t1.start()

	def __ReadFile__(self):
		
		self.Machine = MachineNum
			
		if str(MachineNum) == "MDR1" & Busy_flag == 0:
			contents = "C:\\Users\\kshah2\\Desktop\\file.asc"
			if system.file.fileExists(contents):
				File = system.file.readFileAsString(contents)
				window = system.gui.getWindow('carlos') 	
	 			window.getRootContainer().getComponent("Text Area").text = File
	   			Busy_flag = 0
			else:
				Busy_flag = 1
				self.timerFunc()
		
		elif str(MachineNum) == "MDR2" & Busy_flag == 0:
			contents = "C:\\Users\\kshah2\\Desktop\\file1.asc"
			if system.file.fileExists(contents):
				File = system.file.readFileAsString(contents)
				window = system.gui.getWindow('carlos') 	
				window.getRootContainer().getComponent("Text Area").text = File
		  		Busy_flag = 0
			else:
				Busy_flag = 1
				self.timerFunc()
		else:
			contents = "C:\\Users\\kshah2\\Desktop\\file2.asc"
			if system.file.fileExists(contents):
				File = system.file.readFileAsString(contents)
				window = system.gui.getWindow('carlos') 	
		 		window.getRootContainer().getComponent("Text Area").text = File
		 		Busy_flag = 0
			else:
				Busy_flag = 1
				self.timerFunc()

Calling as -

Name = project.Reading_File.PullingData("MDR1")

Hope for the way…thanks

looks to me like timerFunc never returns a value, my guess is you will experience a UI freeze if you are executing this code from a button press without the use of invokeLater.

I’m not sure I understand exactly what the goal of the program is, perhaps there is a better way to accomplish your task than ‘multi-threading’ (which I see no evidence you are actually doing) in the UI thread.

The __init__ function should always return None. In this case, that will work since it just so happens that timerFunc returns None, but it is best to leave out the return statement for __init__. You could try putting in print statements at various points to see what is getting executed.

Also, it looks like you could accomplish this more simply by using the ‘Timer’ Vision component.

Thanks Guys…Found out how to make it work without functions.