erondem
Posts: 23
Joined: Wed Jul 11, 2018 12:19 pm

Doing multiple jobs at the same time

Wed Jun 26, 2019 3:12 pm

Hi I am running a card reader program in my Raspberry Pi with Python. I've reader which waits for card and when there is card on the reader It sends couple of information to the server and it takes 3-4 seconds. For this 3-4 seconds reader does not work because of response of request.
And when card appears there is olsa GUI which is made with tkinter. They all work seperetaly but I could not work them asynchronously
I've read a lot about asyncronous jobs I am totally confused. Which library and WHY should I use among Processing or Threads or asyncio or something else...

Can anyone help me?

Here is some parts of my code
Reader.py

Code: Select all

from datetime import datetime,timedelta
import sys
from pirc522 import RFID



class Reader(object):
	def __init__(self,accessList,entryLogger):
		self.reader = RFID()
		self.accessList = accessList
		self.entryLogger = entryLogger
		self.ex_time = datetime(2017,12,12,12,12,12)
		self.ex_uid = ""

	
	def read(self):
		cardUID = ""
		self.reader.wait_for_tag()
		(error,data) = self.reader.request()
		(error, uid) = self.reader.anticoll()
		if not error:
			for number in uid[:4]:
				cardUID += format(number,"02X")
			new_time = self._readed_at()
			if(new_time - self.ex_time > timedelta(seconds = 3)):
				self.ex_time = datetime.now()
				return cardUID
				
			
	def is_granted(self,uid):
		if uid is not None and uid in self.accessList:
			self.entryLogger.log(uid)
			print("Access Granted. UID: " + uid)
			return uid

	def _readed_at(self):
		return datetime.now()
	
main.py

Code: Select all

def main():
    download_settings()
    create_folders()
    settings = read_settings()
    accessList = get_user_list(settings)
    configure_scheduler(settings)
    reader = Reader(accessList, entryLogger)
    message_sender = MessageSender(client.check,client.bulk)
    while True:
        authorized_uid = reader.is_granted(reader.read())
        #TODO:If not authorized in AccessList.txt look to the server
        if authorized_uid is not None:
            open_door()
            check_model = CheckModel(configs.DeviceSerialNumber, authorized_uid)
            message.put_message(check_model)
and message_helper.py

Code: Select all

from json_helper import JSONHelper
from database_helper import *
from model_helper import ModelHelper

class Message():
	def __init__(self, queue, client, syncLogger=None, entryLogger=None, errorLogger=None):
		self.queue = queue
		self.entryLogger = entryLogger if entryLogger is not None else None
		self.errorLogger = errorLogger if errorLogger is not None else None
		self.syncLogger = syncLogger if syncLogger is not None else None
		self.DatabaseAction = DBHelper()

	def put_message(self, message):
		self.put_to_queue(self.queue, message)
		self.put_to_db(message)

	def get_message(self):
		return self.get_from_queue(self.queue)

	def put_to_queue(self, queue, message):
		self.queue.put(message)

	def get_from_queue(self, queue):
		if not queue.empty():
			return queue.get()
		else:
			print("Queue is empty")
			return None

	def put_to_db(self, message):
		message = ModelHelper.checkmodel_to_log(message)
		self.DatabaseAction.insert(Record(message.__dict__))

	def get_from_db(self,message,criteria):
		pass



User avatar
MrYsLab
Posts: 435
Joined: Mon Dec 15, 2014 7:14 pm
Location: Noo Joysey, USA

Re: Doing multiple jobs at the same time

Wed Jun 26, 2019 4:37 pm

It is not clear from the code you provided, but your main method which contains a while True loop may be blocking the GUI. Tkinter has its own event loop and you probably should incorporate your while True loop into the tkinter loop by using the tkinter "after" method.

Here is one article that provides an example https://www.geeksforgeeks.org/python-af ... n-tkinter/.

If you are still having problems you may need to do multithreading. Another link: https://gordonlesti.com/use-tkinter-without-mainloop/.

erondem
Posts: 23
Joined: Wed Jul 11, 2018 12:19 pm

Re: Doing multiple jobs at the same time

Mon Jul 01, 2019 7:59 am

MrYsLab wrote:
Wed Jun 26, 2019 4:37 pm
It is not clear from the code you provided, but your main method which contains a while True loop may be blocking the GUI. Tkinter has its own event loop and you probably should incorporate your while True loop into the tkinter loop by using the tkinter "after" method.

Here is one article that provides an example https://www.geeksforgeeks.org/python-af ... n-tkinter/.

If you are still having problems you may need to do multithreading. Another link: https://gordonlesti.com/use-tkinter-without-mainloop/.

Exactly main loop contains an infinite loop which is actually a NRF Card Reader naturally waits for card. BUT while it waits for new cards, I need to update some images and some json files via sending requests to a server. My mind confuses right here.
I have a infinite loop as Reader,
A second loop for GUI which shows some images when certain cards appear
A third loop which takes care of requests to the internet.

So how can I handle with all of these?

User avatar
MrYsLab
Posts: 435
Joined: Mon Dec 15, 2014 7:14 pm
Location: Noo Joysey, USA

Re: Doing multiple jobs at the same time

Mon Jul 01, 2019 11:53 am

To run the loops concurrently, one solution is to use threading. Here is a great article with working examples: https://pymotw.com/3/threading/.

Your GUI would be the main thread and in its initialization method would spawn and start separate threads for the other 2 loops before starting its own main loop.

There are many ways to have the threads communicate with one another. Again, another article that describes how to build a thread-safe queue https://pymotw.com/3/queue/.

Another data structure that can be used is the deque https://pymotw.com/3/collections/deque.html.

If neither of those data structures meets your needs, you can use a shared variable of some sort, but you may need to provide some protection around the variable so that as one thread is reading the data, another thread does not simultaneously update the variable, which may result in corrupt data.
Yet another article: http://effbot.org/zone/thread-synchronization.htm

Hopefully, there is enough material to get you started.

Return to “Python”