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")
Exemple #6
0
    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"]