def error(name, err): try: dt = current_dateTime("Date").replace("/", "_") error_log = f"{os.getcwd()}/master/logs/Error_Log_{dt}.txt" with open(error_log, "a") as f: f.write( f"ERROR OCCURED:// Name: {name} - Description: {err} - Datetime: {current_dateTime()}\n") except Exception as e: print(e)
def checkOutdated(self, csvData): checkOutdatedList = [unit["unit"] for unit in csvData] for row in self.liveWorkload.find(): unit = row["unit"] updated_at = row["updated_at"] sos = row["sos"] workload = row["workload"] threshold = row["threshold"] crew_member_one = row["crew_member_one"] crew_member_two = row["crew_member_two"] task_time = row["task_time"] arrivals = row["arrivals"] post_time = row["post_time"] late_call = row["late_call"] past_eos = row["past_eos"] # Check For Outdated Unit Data If Unit not in new CSV file data if unit not in checkOutdatedList: print( colored(f"Unit {unit} Purged - Last Updated: {updated_at}", "yellow")) if threshold > 0.92: # SAVE TO HISTORIC WORKLOAD historic = { "date": current_dateTime("Date"), "crew_member_one": crew_member_one, "crew_member_two": crew_member_two, "unit": unit, "sos": sos, "task_time": task_time, "arrivals": arrivals, "post_time": post_time, "workload": workload, "late_call": late_call, "past_eos": past_eos } self.historicWorkload.insert_one(historic) print( colored( f"Unit {unit} Added To Historic Workload Database", "yellow")) print( colored( "================================================", "blue")) # DELETE FROM LIVE WORKLOAD self.liveWorkload.delete_one({"unit": unit})
def Log(self): if self.log: obj = self.snapShot() if self.dataType == list: for msg in self.data: obj["log"] = f"{msg} - {current_dateTime('Time')}" self.system.update_one({"date": current_dateTime("Date")}, {"$push": { "logs": obj }}, upsert=False) elif self.dataType == str: obj["log"] = f"{self.data} - {current_dateTime('Time')}" self.system.update_one({"date": current_dateTime("Date")}, {"$push": { "logs": obj }}, upsert=False)
def unitWorkload(self): for unit in self.csvData: sos = unit["sos"] arrivals = unit["arrivals"] task_time = unit["task_time"] post_time = unit["post_time"] # Get Time Difference Between SOS & Current Time current_time = current_dateTime("Time") s1 = sos s2 = str(current_time).split(" ")[-1] FMT = '%H:%M:%S' tdelta = datetime.strptime(s2, FMT) - datetime.strptime(s1, FMT) tdelta = str(tdelta).split(" ")[-1] hours_diff = tdelta[:4] hours_diff = hours_diff.replace(":", ".") # Get Percentage Of Shift Currently Worked percentage_worked = round(float(hours_diff) / 12, 2) # Set Max Threshold and Determine Current Threshold current_threshold = (self.max_threshold / 12) * round( float(hours_diff), 2) # Check If Arrivals Above Zero if arrivals > 0: # Set Max Task and Get Task Differential true_task = (task_time / arrivals) task_dif = self.max_task + true_task # Workload Formula workload = round( ((percentage_worked / task_dif) * 100) + (arrivals / 10), 2) workload = workload - (post_time / 100) # If Arrivals Not More Than Zero, Workload = Current Threshold else: workload = (current_threshold - (post_time / 100)) unit["workload"] = round(workload, 2) unit["threshold"] = round(current_threshold, 2) unit["ratio"] = (round(workload, 2) - round(current_threshold, 2))
def listen(self): if os.path.exists(self.path_to_csv_file): start = time.perf_counter() print(colored("~~~~~~~~~~~~~~~~~~~~~~~~~~~~", "blue")) print(colored("\n[CSV FILE FOUND]", "green")) print(colored("~~~~~~~~~~~~~~~~~~~~~~~~~~~~", "blue")) self.csv.csvFile() csvData = self.csv.csvData csvEnd = time.perf_counter() print( colored(f"--> CSV - Took {round(csvEnd-start, 2)} second(s)\n", "red")) print(colored("\n[HANDLING LIVE WORKLOAD]", "green")) print(colored("~~~~~~~~~~~~~~~~~~~~~~~~~~~~", "blue")) self.liveWorkloadHandler(csvData) liveEnd = time.perf_counter() print( colored( f"--> LIVE - Took {round(liveEnd-csvEnd, 2)} second(s)\n", "red")) print(colored("\n[NOTIFY/LOG]", "green")) print(colored("~~~~~~~~~~~~~~~~~~~~~~~~~~~~", "blue")) self.notifyLog(self.liveWorkloadHandler.notificationList) notifylogEnd = time.perf_counter() print( colored( f"--> NOTIFY/LOG - Took {round(notifylogEnd-liveEnd, 2)} second(s)\n", "red")) print(colored("\n[HANDLING HISTORIC WORKLOAD]", "green")) print(colored("~~~~~~~~~~~~~~~~~~~~~~~~~~~~", "blue")) self.historicWorkloadHandler(csvData) historicEnd = time.perf_counter() print( colored( f"--> HISTORIC - Took {round(historicEnd-notifylogEnd, 2)} second(s)\n", "red")) print(colored("\n[HANDLING SYSTEM]", "green")) print(colored("~~~~~~~~~~~~~~~~~~~~~~~~~~~~", "blue")) self.systemHandler(csvData) systemEnd = time.perf_counter() print( colored( f"--> SYSTEM - Took {round(systemEnd-historicEnd, 2)} second(s)\n", "red")) self.iterationCount = 0 self.cycle += 1 self.csv.csvData.clear() self.liveWorkloadHandler.notificationList.clear() if not self.testing: os.remove(self.path_to_csv_file) end = time.perf_counter() print( colored( f"\n--> Cycle {self.cycle} Complete - {current_dateTime()} - Took {round(end-start, 2)} second(s)\n", "yellow")) self.iterationCount += 1 if self.iterationCount == 120: # 2 minutes without CSV will send notification msg = "[ALERT] - CSV Undetected For 2 Minutes" self.notifyLog(msg, log=False) self.master.insert_one({ "dateTime": current_dateTime(), "message": msg }) if self.iterationCount == 1800: # 30 minutes then place system data invalid self.system.update_one({"date": current_dateTime("Date")}, {"$set": { "valid": False }}, upsert=False) print("[SYSTEM DATA] - Invalid")
def csvFile(self): current_time = current_dateTime("Time") with open(self.path, newline="") as file: reader = csv.reader(file) header = next(reader) filter_by_list = [ 'Unit', 'UnitStartTime', 'ActualTaskTimeUHU', 'Arrivals', 'Textbox8', 'Crew', "PostAssignments", "ActualTimeOnShift" ] ## Get index of param in csv list ## filter_by_list_index = [header.index(i) for i in filter_by_list] checkDuplicates = [] divisions = ["Eastern Division"] for row in reader: if row and row[0] in divisions: unit = row[filter_by_list_index[0]] if unit not in checkDuplicates: checkDuplicates.append(unit) sos = row[filter_by_list_index[1]] task_time = self.convert_to_minutes( row[filter_by_list_index[2]]) task_time = abs(task_time) arrivals = int(row[filter_by_list_index[3]]) if arrivals == "": arrivals = 0 arrivals = self.check_for_jump(unit, arrivals, task_time) post_time = self.convert_to_minutes( row[filter_by_list_index[4]]) crew = row[filter_by_list_index[5]] post_assignments = int(row[filter_by_list_index[6]]) time_on_shift = self.convert_to_minutes( row[filter_by_list_index[7]]) if len(crew) > 0: crew = crew.split("&") crew_member_one = crew[0] crew_member_two = crew[1] crew_member_one = crew_member_one.strip() crew_member_two = crew_member_two.strip() else: crew_member_one = "N/A" crew_member_two = "N/A" voidUnits = ["H", "7", "5", "E", "T"] unitExists = self.liveWorkload.find_one({"unit": unit}) if unitExists: status = unitExists["status"] above_max = unitExists["above_max"] above_current = unitExists["above_current"] late_call = unitExists["late_call"] past_eos = unitExists["past_eos"] drive_time = unitExists["drive_time"] last_drive_time = unitExists["drive_time"] last_task_time = unitExists["task_time"] last_post_time = unitExists["post_time"] last_post = unitExists["last_post"] last_arrivals = unitExists["arrivals"] last_post_assignments = unitExists[ "post_assignments"] else: status = None above_max = False above_current = False late_call = False past_eos = False drive_time = 0 last_drive_time = 0 last_task_time = 0 last_post_time = 0 last_post = 0 last_arrivals = 0 last_post_assignments = 0 if unit[0] not in voidUnits: self.csvData.append({ "updated_at": current_time, "unit": unit, "sos": sos, "shift_average": 0, "time_on_shift": time_on_shift, "task_time": task_time, "arrivals": arrivals, "post_time": post_time, "crew_member_one": crew_member_one, "crew_member_two": crew_member_two, "workload": 0, "threshold": 0, "ratio": 0, "status": status, "above_max": above_max, "above_current": above_current, "late_call": late_call, "past_eos": past_eos, "post_assignments": post_assignments, "drive_time": drive_time, "last_drive_time": last_drive_time, "last_task_time": last_task_time, "last_post_time": last_post_time, "last_post": last_post, "last_arrivals": last_arrivals, "last_post_assignments": last_post_assignments })
def unitStatus(self): for unit in self.csvData: sos = unit["sos"] status = unit["status"] workload = unit["workload"] threshold = unit["threshold"] above_max = unit["above_max"] above_current = unit["above_current"] late_call = unit["late_call"] past_eos = unit["past_eos"] time_on_shift = unit["time_on_shift"] drive_time = unit["drive_time"] last_drive_time = unit["last_drive_time"] task_time = unit["task_time"] last_task_time = unit["last_task_time"] post_time = unit["post_time"] last_post_time = unit["last_post_time"] last_post = unit["last_post"] arrivals = unit["arrivals"] last_arrivals = unit["last_arrivals"] post_assignments = unit["post_assignments"] last_post_assignments = unit["last_post_assignments"] if threshold < self.max_threshold: if task_time > last_task_time: if status == "Fueling" or status == "EOS" or status == "Late Call": status = "Late Call" else: status = "On Call" task_difference = (task_time - last_task_time) self.system.accumulateToSystem("on_call_time", task_difference) elif post_time > last_post_time: if threshold < 0.92: status = "Posting" post_difference = (post_time - last_post_time) self.system.accumulateToSystem("post_time", post_difference) elif threshold >= 0.92 and threshold < 0.94: status = "Fueling" elif threshold >= 0.94 and threshold < self.max_threshold: status = "EOS" unit["last_post"] = current_dateTime("Time")[0:5] else: if threshold < 0.92: drive_time = (time_on_shift - (task_time + post_time)) status = "Driving" drive_time_difference = (drive_time - last_drive_time) unit["drive_time"] += drive_time_difference self.system.accumulateToSystem("drive_time", drive_time_difference) elif threshold >= 0.92 and threshold < 0.94: status = "Fueling" elif threshold >= 0.94 and threshold < self.max_threshold: status = "EOS" unit["late_call"] = False else: status = "Past EOS" if threshold >= 1.5: status = "SOS" unit["workload"] = 0 unit["threshold"] = 0 if unit["workload"] >= self.max_threshold: unit["above_max"] = True unit["above_current"] = True if not above_max: msg = f"Unit {unit['unit']} Above Max Threshold" self.notificationList.append(msg) elif unit["workload"] < self.max_threshold and unit[ "workload"] > unit["threshold"]: unit["above_current"] = True unit["above_max"] = False elif unit["workload"] <= unit["threshold"]: unit["above_current"] = False unit["above_max"] = False if status == "Late Call" and not late_call: unit["late_call"] = True msg = f"Unit {unit['unit']} Received Late Call" self.notificationList.append(msg) self.system.accumulateToSystem("late_calls", 1) if status == "Past EOS" and not past_eos: unit["past_eos"] = True msg = f"Unit {unit['unit']} Past EOS" self.notificationList.append(msg) self.system.accumulateToSystem("past_eos", 1) unit["status"] = status if arrivals > last_arrivals: arrivals_difference = (arrivals - last_arrivals) self.system.accumulateToSystem("calls", arrivals_difference) if post_assignments > last_post_assignments: post_assignments_difference = (post_assignments - last_post_assignments) self.system.accumulateToSystem("post_assignments", post_assignments_difference) del unit["last_task_time"] del unit["last_post_time"] del unit["last_drive_time"] del unit["last_post_assignments"] del unit["last_arrivals"]