from datetime import datetime as dt import time import json import math class RuntimeStats: def __init__(self): self.runs = {} self.currentRun = 0 self.today = "" self.todayString = "" def manageTime(self): if self.todayString != dt.strftime(dt.today(), "%Y-%m-%d"): if self.runs[self.todayString]["run_" + str(self.currentRun)]["start"] and not self.runs[self.todayString]["run_" + str(self.currentRun)]["end"]: self.runs[self.todayString]["run_" + str(self.currentRun)]["end"] = time.mktime(dt.strptime(self.todayString + " 23:59:59", "%Y-%m-%d %H:%M:%S").timetuple()) self.addDay() self.today = dt.today() self.todayString = dt.strftime(self.today, "%Y-%m-%d") days = list(self.runs.keys()) days.sort() while (dt.strptime(days[-1],"%Y-%m-%d") - dt.strptime(days[0], "%Y-%m-%d")).days > 30: self.removeDay(day=days[0]) days = list(self.runs.keys()) days.sort() def addHertzDataPoint(self, frequency): if frequency > 0: self.manageTime() try: self.runs[self.todayString]["run_" + str(self.currentRun)]["frequencies"].append(frequency) except: self.runs[self.todayString]["run_" + str(self.currentRun)]["frequencies"] = [frequency] def startRun(self): if self.checkRunning(): self.endRun() self.runs[self.todayString]["run_" + str(self.currentRun)]["start"] = time.time() def endRun(self): self.runs[self.todayString]["run_" + str(self.currentRun)]["end"] = time.time() self.currentRun += 1 self.runs[self.todayString]["run_" + str(self.currentRun)] = {"start":0, "end": 0, "frequencies":[]} def checkRunning(self): if self.runs[self.todayString]["run_" + str(self.currentRun)]["start"] and not self.runs[self.todayString]["run_" + str(self.currentRun)]["end"]: return True return False def addDay(self): self.today = dt.today() self.todayString = dt.strftime(self.today, "%Y-%m-%d") self.currentRun = 1 self.runs[self.todayString] = {} self.runs[self.todayString]["run_" + str(self.currentRun)] = {"start":0, "end": 0, "frequencies":[]} def countRunsDay(self, day=None): if not day: day = self.todayString return len(self.runs[day].keys()) def countRunsMultiDay(self, numDays=30): total_runs = 0 for day in list(self.runs.keys()): total_runs += self.countRunsDay(day=day) return total_runs def calculateAverageHertzDay(self, day=None, returnArray=False): dayFrequencies = [] if not day: day = self.todayString for run in list(self.runs[day].keys()): try: dayFrequencies += self.runs[day][run]["frequencies"] except Exception as e: print("{} missing frequency data for {}".format(day,run)) if returnArray: return dayFrequencies return round(math.fsum(dayFrequencies)/len(dayFrequencies),2) def calculateAverageHertzMultiDay(self, numDays=30): self.manageTime() frequencies = [] for day in list(self.runs.keys()): if not day == self.todayString and (dt.strptime(self.todayString, "%Y-%m-%d") - dt.strptime(day, "%Y-%m-%d")).days <= numDays: try: frequencies += self.calculateAverageHertzDay(day=day, returnArray=True) except Exception as e: print("{} missing frequency data".format(day)) if len(frequencies): return round(math.fsum(frequencies)/len(frequencies), 2) return 0 def calculateRunTimeDay(self, day=None, convertToHours=True): total_time = 0 if not day: day = self.todayString for run in list(self.runs[day].keys()): total_time = self.runs[day][run]["end"] - self.runs[day][run]["start"] + total_time if convertToHours: return self.convertSecondstoHours(total_time) return total_time def calculateRunTimeMultiDay(self, numDays=30, convertToHours=True): total_time = 0 for day in list(self.runs.keys()): if not day == self.todayString and (dt.strptime(self.todayString, "%Y-%m-%d") - dt.strptime(day, "%Y-%m-%d")).days <= numDays: total_time += self.calculateRunTimeDay(day=day, convertToHours=False) if convertToHours: return self.convertSecondstoHours(total_time) return total_time def calculateRunPercentDay(self, day=None, precise=False): if not day: day = self.todayString if precise: return (self.calculateRunTimeDay(day=day)/24) * 100 return round((self.calculateRunTimeDay(day=day)/24) * 100, 2) def calculateRunPercentMultiDay(self, numDays=30, precise=False): self.manageTime() if precise: return (self.calculateRunTimeMultiDay()/(24*numDays)) * 100 return round((self.calculateRunTimeMultiDay()/(24*numDays)) * 100,2) def removeDay(self, day=None): if not day: raise Exception("Day can not be None") print("removing day {}".format(day)) del self.runs[day] def convertSecondstoHours(self, seconds): return round(seconds / (60*60),2) def loadDataFromFile(self, filePath="./runtimestats.json"): try: with open(filePath, "r") as f: temp = json.load(f) self.runs = temp["data"] self.currentRun = temp["current_run"] self.today = dt.strptime(temp["current_day"], "%Y-%m-%d") self.todayString = temp["current_day"] self.manageTime() except: print("Could not find file at {}".format(filePath)) print("creating file") self.addDay() try: with open(filePath, "w") as f: d = { "current_run": self.currentRun, "current_day": self.todayString, "data": self.runs } json.dump(d, f, indent=4) except Exception as e: print(e) def saveDataToFile(self, filePath="./runtimestats.json"): try: print("Saving Runs") with open(filePath, "w") as f: d = { "current_run": self.currentRun, "current_day": self.todayString, "data": self.runs } json.dump(d, f, indent=4) except Exception as e: print(e)