Jan-29-2020, 11:21 AM
Hi,
I am trying to automate the production system using multi-threading. I have a class workstation and it has a function "drawing_thread" that runs a separate thread for each instance of that class, currently, i have three instances of that class and they are supposed to run three treads on certain conditions but only first thread is working well not others even the check condition is true for other threads.
Workstation class code
Function in main that calls the drawing_thread function
WS_obj_list, contains the instances of class
OrderList, is global variable that contains the drawing model
I am trying to automate the production system using multi-threading. I have a class workstation and it has a function "drawing_thread" that runs a separate thread for each instance of that class, currently, i have three instances of that class and they are supposed to run three treads on certain conditions but only first thread is working well not others even the check condition is true for other threads.
Workstation class code
# Import libraries import requests,time,db_quries import threading from datetime import datetime import helper_functions as HF LocIP = '192.168.100.100' # Local port for server LocPort = 4321 class Workstation(): # Call the Thread class's init function def __init__(self,FCell): """ constructor for class workstation :param FCell: """ self.FCell = FCell # cell number #initial values of component's flag self.frame_done = True self.screen_done = False self.kpad_done = False #flags for order compeltion self.make = 1 self.complete = 0 self.thread_flag=True #mutators for object variables def make_setter(self): self.make = self.make+1 #print('FL1: Make ',self.make) def set_m(self,m): self.make=m def complete_setter(self,complete): self.complete =complete #print('FL1: complete ',self.complete) def set_frame(self, value): self.frame_done = value def set_screen(self, value): self.screen_done = value def set_kpad(self, value): self.kpad_done = value def set_thread_flag(self,value): self.thread_flag = value #****************************** # Events subscriptions #****************************** # Event subscriptions for conveyor def event_subscriptions_4_zones(self, zone_name,LocIP, LocPort,i): """ this method subscribe a workstation to the event for all zones of conveyor on that workstation :param zone_name:zones on convyor :param LocIP:IP of application :param LocPort:application port waiting for response from RTU :return: nothing """ # application (192.168.103.200:4321) Subscribe to events on Zones # Prepare URL and body for the environment URLb = 'http://192.168.' + self.FCell + '.2/rest/events/' + zone_name + '_Changed/notifs' # application URl body = {"destUrl": "http://" + LocIP + ':' + str(LocPort)+'/CNV_events'} # Submit POST request #print(body) r = requests.post(URLb, json=body) # Collect on cont the response's body cont = r.json() # Shows information and subscription id in console # populating subscription Table # db_quries.insert_subscriptions((self.FCell, 'CNV', 'Z' + str(i), # str(r.status_code),r.reason, # datetime.now().strftime("%m/%d/%Y, %H:%M:%S"))) # time.sleep(2) print('Workstation ',self.FCell,'_EVENT_' + zone_name + '_Changed subscription', r.status_code, r.reason, cont['id']) # Event subscriptions for Robot def event_subscriptions_4_robot(self, LocIP, LocPort, event_name): """ this method subscribe a workstation to the events for robot on that workstation :param event_name:robot actions :param LocIP:IP of application :param LocPort:application port waiting for response from RTU :return: nothing """ # Subscribe 192.168.103.200:4321 to events on event_name # Prepare URL and body for the environment URLb = 'http://192.168.' + self.FCell + '.1/rest/events/' + event_name + '/notifs' body = {"destUrl": "http://" + LocIP + ':' + str(LocPort)+'/rob_events'} # Submit POST request r = requests.post(URLb, json=body)#,data={"FCell":self.FCell} # Collect on cont the response's body cont = r.json() # Shows information and subscription id in console # populating subscription Table # db_quries.insert_subscriptions((self.FCell, 'Robot', 'DrawStartExecution', # str(r.status_code),r.reason, # datetime.now().strftime("%m/%d/%Y, %H:%M:%S"))) # time.sleep(2) print('Workstation ',self.FCell,'_EVENT_' + event_name + '_Changed subscription', r.status_code, r.reason, cont) #****************************** # Invoking services #****************************** #invoking services on conveyor def get_zone_status(self, zone_name): """ checks weather a zone is occupied or empty :param zone_name:zone at conveyor :return:pallet ID at zone """ URLb = 'http://192.168.' + self.FCell + '.2/rest/services/' + zone_name # Submit POST request body = {} # if zone_name == 'Z1': r = requests.post(URLb, json=body) #print('Pallet status at ' + zone_name + ' :',r.json()) # print('Pallet status at ' + zone_name + ' :',r.text) # try: # return r.json()['PalletID'] # # except ValueError: # print('Decoding JSON has failed......\nPlease rebot CNV RTU! at ',self.FCell) # return r.json()['PalletID'] # else: #r = requests.post(URLb, json=body) #status_all='-1' # r.content>>> to see contents in bytes # r.text>>> serilaized JSON (json string) then use json.loads to deserialized (python dict) # more simpler way to get deserialized use .json() method try: return r.json()['PalletID'] except ValueError: print('Decoding JSON has failed......\nPlease rebot CNV RTU! at ',self.FCell) return r.json()['PalletID'] #print('Pallet status at ' + zone_name + ' :',r.json()['PalletID']) def TransZone(self, transfer): """ execute the pallet transfer on conveyor :param transfer:zone name according to FASTory API :return: """ # Prepare URL for the environment URLa = 'http://192.168.' + self.FCell + '.2/rest/services/TransZone' + str(transfer) # Submit POST request to app for getting event body r = requests.post(URLa, json={"destUrl": ""}) # Shows response in console # print('Service TransZone' + transfer, r.status_code, r.reason) # if r.status_code ==200: # db_quries.insert_services((self.FCell,'Service TransZone ' + transfer, # str(r.status_code),r.reason, # datetime.now().strftime("%m/%d/%Y, %H:%M:%S"))) # # else: # db_quries.insert_services((self.FCell, 'Service TransZone ' + transfer, # str(r.status_code),r.reason, # datetime.now().strftime("%m/%d/%Y, %H:%M:%S"))) #invoking services on robot def DrawingRecipes(self, drawing): """ :param drawing:recipes of cell phone model :return: """ # Prepare URL for the environment URLa = 'http://192.168.' + self.FCell + '.1/rest/services/' + drawing # Submit POST request headers={"Content-Type":"application/json"} r = requests.post(URLa, json={"destUrl": ""}, headers=headers) #Shows response in console print('\nService ',drawing, r.status_code, r.reason,URLa) # if r.status_code ==200: # db_quries.insert_services((self.FCell,'Service ' +drawing, # str(r.status_code),r.reason, # datetime.now().strftime("%m/%d/%Y, %H:%M:%S"))) # time.sleep(2) # else: # db_quries.insert_services((self.FCell, 'Service ' + drawing, # str(r.status_code),r.reason, # datetime.now().strftime("%m/%d/%Y, %H:%M:%S"))) # time.sleep(2) def changePenColor(self, desire_color): """ All Grippers have incorrect offset and stuck with pallet during changing pen so i am not calling it. :param desire_color: :return: """ # Prepare URL for the environment URLa = 'http://192.168.' + self.FCell + '.1/rest/services/' + desire_color # Submit POST request r = requests.post(URLa, json={"destUrl": ""}) # Shows response in console #print('\nService ',desire_color, r.status_code, r.reason) #******************************************* # Pallet control Logic and Drawing thread #******************************************* def pallet_control(self): """ :param self: :return: """ # routing between Z2 and Z4 if (self.get_zone_status('Z1') != '-1' and self.get_zone_status('Z2') == '-1' ): self.TransZone('12') time.sleep(1) elif (self.get_zone_status('Z1') != '-1' and self.get_zone_status('Z2') != '-1' ): # print('Zone 2 is busy') self.TransZone('14') # print('Discarded Order is: ', pending_order.pop(2)) time.sleep(1) if (self.get_zone_status('Z5') == '-1'): self.TransZone('45') time.sleep(1) # next station zone transfer if (self.get_zone_status('Z2') != '-1' and self.get_zone_status('Z3') == '-1' ): self.TransZone('23') time.sleep(1) ####################################################### def production(self,WS_obj, OrderList): # unpack orders for i in range(len(OrderList)): if len(OrderList) == 0: print('Order list is empty..........') break ord_under_prod = OrderList.pop(0) print(i, len(OrderList), ord_under_prod) ord_num = list(ord_under_prod.keys())[0] order_specs = ord_under_prod[ord_num][0:4] order_quantity = ord_under_prod[ord_num][-1] # Drawing process starts for j in range(1, order_quantity + 1): print(j, 'OUTside While\n') while WS_obj.complete != 1: WS_obj.pallet_control() # print('Helper ',WS_obj.FCell) time.sleep(5) # modification if WS_obj.get_zone_status('Z3') != '-1': if (WS_obj.make == 1 and WS_obj.frame_done == True): WS_obj.DrawingRecipes(order_specs[0]) print('app_6:Printing Frame on....' + WS_obj.FCell, WS_obj.frame_done) WS_obj.set_frame(False) # time.sleep(1) if (WS_obj.make == 2 and WS_obj.screen_done == True): WS_obj.DrawingRecipes(order_specs[1]) print('app_7:Printing Screen on....' + WS_obj.FCell, WS_obj.screen_done) WS_obj.set_screen(False) # time.sleep(1) if (WS_obj.make == 3 and WS_obj.kpad_done == True): WS_obj.DrawingRecipes(order_specs[2]) print('app_8:Printing Keypad on....' + WS_obj.FCell, WS_obj.kpad_done) WS_obj.set_kpad(False) # time.sleep(1) if WS_obj.complete == 1: WS_obj.set_frame(True) WS_obj.TransZone('35') # passing to next station print('completed order is: ', WS_obj.FCell, tuple( (ord_num, order_specs[0], order_specs[1], order_specs[2], order_specs[3], str(j) + '/' + str(order_quantity)) ) ) WS_obj.complete_setter(0) print(WS_obj.complete, WS_obj.frame_done, WS_obj.screen_done, WS_obj.kpad_done) time.sleep(1) # WS_obj.set_thread_flag(False) ###################################################### def drawing_thread(self,WS_obj, OrderList): self.thread_flag = False drawing = threading.Thread(target=self.production, args=(WS_obj, OrderList)) drawing.start() ############################################################
Function in main that calls the drawing_thread function
WS_obj_list, contains the instances of class
OrderList, is global variable that contains the drawing model
def process_thread(): while True: if WS_obj_list[0].thread_flag and WS_obj_list[0].get_zone_status('Z1') != '-1': WS_obj_list[0].drawing_thread((WS_obj_list[0], OrderList)) if WS_obj_list[1].thread_flag and WS_obj_list[1].get_zone_status('Z1') != '-1': # WS_obj_list[1].drawing_thread((WS_obj_list[1], OrderList)) time.sleep(5)
- I can't figure out why other threads are not working, it seems that they are hanged.
- according to my understanding each object is starting its own threads so there is no conflict between common resource sharing