From bc9e45e18f276c4236bfe213629dac800fdb486f Mon Sep 17 00:00:00 2001 From: Nico Melone Date: Tue, 17 Jan 2023 23:06:47 -0600 Subject: [PATCH] added runtimestats --- .DS_Store | Bin 18436 -> 18436 bytes abbflow/modbusMap.json | 291 ++++++++++++++++++++++++++ piflow/PiFlow.py | 20 ++ piflow/runtimeStats.py | 157 ++++++++++++++ piflow/runtimestats.ipynb | 419 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 887 insertions(+) create mode 100644 abbflow/modbusMap.json create mode 100644 piflow/runtimeStats.py create mode 100644 piflow/runtimestats.ipynb diff --git a/.DS_Store b/.DS_Store index 024b40cd7cdd0d1bbd486d341fc4f20e96da5656..c8ca8674d4beec07de0acd0a26f4bc3d86cc16b0 100644 GIT binary patch delta 23 fcmZpfz}PZ@al#5l#*Hhb#U@V@mE3$+Ox+LwXDtXp delta 21 dcmZpfz}PZ@al#5lhK(zw#TXek9~HAV1OQSx2JZj> diff --git a/abbflow/modbusMap.json b/abbflow/modbusMap.json new file mode 100644 index 0000000..8f2b34e --- /dev/null +++ b/abbflow/modbusMap.json @@ -0,0 +1,291 @@ +{ + "1": { + "c": "M1-232", + "b": "9600", + "addresses": { + "1": { + "2-2": { + "ah": "", + "bytary": null, + "al": "", + "vn": "Volume Flow", + "ct": "number", + "le": "32", + "grp": "3600", + "la": 1301.77, + "chn": "volume_flow", + "un": "1", + "dn": "abbflow", + "da": "1", + "lrt": 1502726350.068169, + "a": "4003", + "c": "20.0", + "misc_u": "MCF/Day", + "f": "4", + "mrt": "60", + "m": "none", + "m1ch": "2-2", + "mv": "0", + "s": "On", + "r": "0-5000", + "t": "float", + "vm": null + }, + "2-3": { + "ah": "", + "bytary": null, + "al": "0", + "vn": "Today Volume", + "ct": "number", + "le": "32", + "grp": "3600", + "la": 214.742, + "chn": "today_volume", + "un": "1", + "dn": "abbflow", + "da": "1", + "lrt": 1502726379.1855018, + "r": "0-1000", + "a": "4005", + "c": "10.0", + "misc_u": "MCF", + "f": "4", + "mrt": "60", + "m": "none", + "m1ch": "2-3", + "s": "On", + "mv": "0", + "t": "float", + "vm": null + }, + "2-1": { + "ah": "", + "bytary": null, + "al": "", + "vn": "Battery Voltage", + "ct": "number", + "le": "32", + "grp": "3600", + "la": 12.477, + "chn": "battery_voltage", + "r": "0-50", + "dn": "abbflow", + "da": "1", + "lrt": 1502725891.07102, + "a": "4001", + "c": "5", + "misc_u": "V", + "f": "4", + "mrt": "60", + "m": "none", + "m1ch": "2-1", + "mv": "0", + "s": "On", + "un": "1", + "t": "float", + "vm": null + }, + "2-6": { + "ah": "", + "bytary": null, + "al": "0", + "vn": "Last Calc. Period Volume", + "ct": "number", + "le": "32", + "grp": "86400", + "la": 14.691, + "chn": "last_calculation_period_volume", + "un": "1", + "dn": "abbflow", + "da": "1", + "lrt": 1502682560.730711, + "a": "4011", + "c": "10", + "misc_u": "SCF", + "f": "4", + "mrt": "60", + "m": "none", + "m1ch": "2-6", + "mv": "0", + "s": "On", + "r": "0-1000000", + "t": "float", + "vm": null + }, + "2-7": { + "ah": "", + "bytary": null, + "al": "0", + "vn": "Differential Pressure", + "ct": "number", + "le": "32", + "grp": "3600", + "la": 3.095, + "chn": "differential_pressure", + "un": "1", + "dn": "abbflow", + "da": "1", + "lrt": 1502725891.811299, + "r": "0-500", + "a": "4013", + "c": "5", + "misc_u": "InH20", + "f": "4", + "mrt": "60", + "m": "none", + "m1ch": "2-7", + "s": "On", + "mv": "0", + "t": "float", + "vm": null + }, + "2-4": { + "ah": "", + "bytary": null, + "al": "0", + "vn": "Yesterday Volume", + "ct": "number", + "le": "32", + "grp": "21600", + "la": 640.448, + "chn": "yesterday_volume", + "un": "1", + "dn": "abbflow", + "da": "1", + "lrt": 1502517692.3270173, + "a": "4007", + "c": "10.0", + "misc_u": "MCF", + "f": "4", + "mrt": "60", + "m": "none", + "m1ch": "2-4", + "mv": "0", + "s": "On", + "r": "0-5000", + "t": "float", + "vm": null + }, + "2-5": { + "ah": "", + "bytary": null, + "al": "0", + "vn": "Accumulated Volume", + "ct": "number", + "le": "32", + "grp": "3600", + "la": 23666.424, + "chn": "accumulated_volume", + "un": "1", + "dn": "abbflow", + "da": "1", + "lrt": 1502726134.0120883, + "a": "4009", + "c": "10", + "misc_u": "MCF", + "f": "4", + "mrt": "60", + "m": "none", + "m1ch": "2-5", + "mv": "0", + "s": "On", + "r": "0-1000000", + "t": "float", + "vm": null + }, + "2-8": { + "ah": "", + "bytary": null, + "al": "0", + "vn": "Static Pressure", + "ct": "number", + "le": "32", + "grp": "3600", + "la": 27.048, + "chn": "static_pressure", + "r": "0-250", + "un": "1", + "dn": "abbflow", + "da": "1", + "lrt": 1502725884.245366, + "a": "4015", + "c": "5", + "misc_u": "PSIA", + "f": "4", + "mrt": "60", + "m": "none", + "m1ch": "2-8", + "s": "On", + "mv": "0", + "t": "float", + "vm": null + }, + "2-9": { + "ah": "", + "bytary": null, + "al": "0", + "vn": "Temperature", + "ct": "number", + "le": "32", + "grp": "3600", + "la": 85.208, + "chn": "temperature", + "r": "0-300", + "un": "1", + "dn": "abbflow", + "da": "1", + "lrt": 1502724763.458232, + "a": "4017", + "c": "5", + "misc_u": "deg F", + "f": "4", + "mrt": "60", + "m": "none", + "m1ch": "2-9", + "s": "On", + "mv": "0", + "t": "float", + "vm": null + }, + "2-10": { + "ah": "", + "bytary": null, + "al": "", + "vn": "Charger Voltage", + "ct": "number", + "le": "32", + "grp": "3600", + "la": 13.356, + "chn": "charger_voltage", + "r": "0-50", + "dn": "abbflow", + "da": "1", + "lrt": 1502725893.760519, + "a": "4019", + "c": "5", + "misc_u": "V", + "f": "4", + "mrt": "60", + "m": "none", + "m1ch": "2-10", + "mv": "0", + "s": "On", + "un": "1", + "t": "float", + "vm": null + } + } + }, + "f": "Off", + "p": "", + "s": "1" + }, + "2": { + "c": "M1-232", + "b": "9600", + "addresses": {}, + "f": "Off", + "p": "", + "s": "1" + } +} \ No newline at end of file diff --git a/piflow/PiFlow.py b/piflow/PiFlow.py index bd81419..18eed1d 100644 --- a/piflow/PiFlow.py +++ b/piflow/PiFlow.py @@ -89,6 +89,7 @@ except: from Tags import tags CHANNELS = tags +from runtimeStats import RuntimeStats as RTS class start(threading.Thread, deviceBase): """Start class required by Meshify.""" @@ -110,6 +111,8 @@ class start(threading.Thread, deviceBase): self.public_ip_address_last_checked = 0 self.status = "" self.alarm = "" + self.rts = RTS() + self.rts.loadDataFromFile() threading.Thread.start(self) # this is a required function for all drivers, its goal is to upload some piece of data @@ -194,6 +197,23 @@ class start(threading.Thread, deviceBase): self.sendtodbDev(1, "run_status", "Running", 0, 'PiFlow') else: self.sendtodbDev(1,"run_status", "Stopped", 0, 'PiFlow') + elif chan.mesh_name == "run_status": + if "Operating" in val and not self.rts.runs[self.rts.todayString]["run_" + str(self.rts.currentRun)]["start"]: + self.rts.startRun() + self.rts.saveDataToFile() + elif "Stopped" in val and self.rts.runs[self.rts.todayString]["run_" + str(self.rts.currentRun)]["start"] and not self.rts.runs[self.rts.todayString]["run_" + str(self.rts.currentRun)]["end"]: + self.rts.endRun() + self.rts.saveDataToFile() + if chan.check(val, self.force_send): + self.sendtodbDev(1, chan.mesh_name, chan.value, 0, 'PiFlow') + self.sendtodbDev(1, "percentRunTime30Days", self.rts.calculateRunPercentMultiDay(), 0,'PiFlow') + elif chan.mesh_name == "frequency": + if val > 0: + self.rts.addHertzDataPoint(val) + self.rts.saveDataToFile() + if chan.check(val, self.force_send): + self.sendtodbDev(1, chan.mesh_name, chan.value, 0, 'PiFlow') + self.sendtodbDev(1, "avgFrequency30Days", self.rts.calculateAverageHertzMultiDay(),0,'PiFlow') elif chan.mesh_name == "remote_start": if chan.check(val, self.force_send): self.sendtodbDev(1, chan.mesh_name, chan.value, 0, 'PiFlow') diff --git a/piflow/runtimeStats.py b/piflow/runtimeStats.py new file mode 100644 index 0000000..9d2c346 --- /dev/null +++ b/piflow/runtimeStats.py @@ -0,0 +1,157 @@ +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.today != dt.today(): + 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() + 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): + 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() + + 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()): + try: + frequencies += self.calculateAverageHertzDay(day=day, returnArray=True) + except Exception as e: + print("{} missing frequency data".format(day)) + return round(math.fsum(frequencies)/len(frequencies), 2) + + 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()): + 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) \ No newline at end of file diff --git a/piflow/runtimestats.ipynb b/piflow/runtimestats.ipynb new file mode 100644 index 0000000..cb4f365 --- /dev/null +++ b/piflow/runtimestats.ipynb @@ -0,0 +1,419 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from datetime import datetime as dt\n", + "from datetime import timedelta as td\n", + "from time import sleep\n", + "import json\n", + "import math" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "class RuntimeStats:\n", + " \n", + " def __init__(self):\n", + " self.runs = {}\n", + " self.currentRun = 1\n", + " self.today = dt.today()\n", + " self.todayString = str(self.today.year)+\"-\"+str(self.today.month)+\"-\"+str(self.today.day)\n", + "\n", + " def addHertzDataPoint(self, frequency):\n", + " try:\n", + " self.runs[self.todayString][\"run_\" + str(self.currentRun)][\"frequencies\"].append(frequency)\n", + " except:\n", + " self.runs[self.todayString][\"run_\" + str(self.currentRun)][\"frequencies\"] = [frequency]\n", + "\n", + " def startRun(self):\n", + " self.runs[self.todayString][\"run_\" + str(self.currentRun)] = {\"start\": dt.timestamp(dt.now())}\n", + " \n", + "\n", + " def endRun(self):\n", + " self.runs[self.todayString][\"run_\" + str(self.currentRun)][\"end\"] = dt.timestamp(self.today) \n", + " self.currentRun += 1\n", + "\n", + " def countRunsDay(self, day=None):\n", + " if not day:\n", + " day = self.todayString\n", + " return len(self.runs[day].keys())\n", + "\n", + " def countRunsMultiDay(self, numDays=30):\n", + " total_runs = 0\n", + " for day in list(self.runs.keys()):\n", + " total_runs += self.countRunsDay(day=day)\n", + " return total_runs\n", + "\n", + " def calculateAverageHertzDay(self, day=None, returnArray=False):\n", + " dayFrequencies = []\n", + " if not day:\n", + " day = self.todayString\n", + " for run in list(self.runs[day].keys()):\n", + " try:\n", + " dayFrequencies += self.runs[day][run][\"frequencies\"]\n", + " except Exception as e:\n", + " print(\"{} missing frequency data for {}\".format(day,run))\n", + " if returnArray:\n", + " return dayFrequencies\n", + " return round(math.fsum(dayFrequencies)/len(dayFrequencies),2)\n", + "\n", + " def calculateAverageHertzMultiDay(self, numDays=30):\n", + " frequencies = []\n", + " for day in list(self.runs.keys()):\n", + " try:\n", + " frequencies += self.calculateAverageHertzDay(day=day, returnArray=True)\n", + " except Exception as e:\n", + " print(\"{} missing frequency data\".format(day))\n", + " return round(math.fsum(frequencies)/len(frequencies), 2)\n", + " \n", + " def calculateRunTimeDay(self, day=None, convertToHours=True):\n", + " total_time = 0\n", + " if not day:\n", + " day = self.todayString\n", + " for key in list(self.runs[day].keys()):\n", + " total_time = self.runs[day][key][\"end\"] - self.runs[day][key][\"start\"] + total_time\n", + " if convertToHours:\n", + " return RuntimeStats.convertSecondstoHours(total_time)\n", + " return total_time\n", + "\n", + " def calculateRunTimeMultiDay(self, numDays=30, convertToHours=True):\n", + " total_time = 0\n", + " for day in list(self.runs.keys()):\n", + " total_time += self.calculateRunTimeDay(day=day, convertToHours=False)\n", + " if convertToHours:\n", + " return RuntimeStats.convertSecondstoHours(total_time)\n", + " return total_time\n", + " \n", + " def calculateRunPercentDay(self, day=None, precise=False):\n", + " if not day:\n", + " day = self.todayString\n", + " if precise:\n", + " return (self.calculateRunTimeDay(day=day)/24) * 100\n", + " return round((self.calculateRunTimeDay(day=day)/24) * 100, 2)\n", + " \n", + "\n", + " def calculateRunPercentMultiDay(self, numDays=30, precise=False):\n", + " if precise:\n", + " return (self.calculateRunTimeMultiDay()/(24*numDays)) * 100\n", + " return round((self.calculateRunTimeMultiDay()/(24*numDays)) * 100,2)\n", + "\n", + " def removeDay(self, day=None):\n", + " if not day:\n", + " raise Exception(\"Day can not be None\")\n", + " del self.runs[day]\n", + " \n", + " def convertSecondstoHours(seconds):\n", + " return round(seconds / (60*60),2)\n", + "\n", + " def loadDataFromFile(self, filePath=\"../runtimestats.json\"):\n", + " try:\n", + " with open(filePath, \"r\") as f:\n", + " self.runs = json.load(f)\n", + " except FileExistsError:\n", + " print(\"Could not find file at {}\".format(filePath))\n", + " except FileNotFoundError:\n", + " print(\"Could not find file at {}\".format(filePath))\n", + " print(\"creating file\")\n", + " try:\n", + " with open(filePath, \"w\") as f:\n", + " json.dump(self.runs, f, indent=4)\n", + " except Exception as e:\n", + " print(e)\n", + " except Exception as e:\n", + " print(e)\n", + "\n", + " def saveDataToFile(self, filePath=\"../runtimestats.json\"):\n", + " try:\n", + " print(\"Saving Runs\")\n", + " with open(filePath, \"w+\") as f:\n", + " json.dump(self.runs, f, indent=4)\n", + " except FileNotFoundError:\n", + " print(\"Could not find file at {}\".format(filePath))\n", + " except Exception as e:\n", + " print(e)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{}\n", + "{'2023-1-11': {'run_1': {'start': 1673465959.694776, 'frequencies': [67, 65, 59, 62, 100], 'end': 1673475545.313309}, 'run_2': {'start': 1673469145.271416, 'end': 1673469136.691883, 'frequencies': [100, 99, 98, 87, 56, 56, 58, 67]}}, '2023-1-10': {'run_1': {'start': 1673465959.694776, 'frequencies': [67, 65, 59, 62], 'end': 1673469136.691883}, 'run_2': {'start': 1673469145.271416, 'end': 1673469136.691883}}, '2023-1-9': {'run_1': {'start': 1673465959.694776, 'frequencies': [67, 65, 59, 62], 'end': 1673469136.691883}, 'run_2': {'start': 1673469145.271416, 'end': 1673469136.691883}}}\n" + ] + } + ], + "source": [ + "rts = RuntimeStats()\n", + "print(rts.runs)\n", + "path = \"/Users/nico/Documents/test/runtimestats.json\"\n", + "rts.loadDataFromFile(filePath=path)\n", + "print(rts.runs)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "rts.endRun()\n", + "print(rts.runs)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "rts.saveDataToFile(filePath=path)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "rts.startRun()\n", + "print(rts.runs)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "rts.countRunsDay()" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2.66" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rts.calculateRunTimeDay(day=\"2023-1-11\")" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "11.08" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rts.calculateRunPercentDay(day=\"2023-1-11\")" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.61" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rts.calculateRunPercentMultiDay()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "rts.calculateRunTimeMultiDay()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "rts.addHertzDataPoint(67)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "74.92\n", + "2023-1-10 missing frequency data for run_2\n", + "2023-1-9 missing frequency data for run_2\n", + "70.48\n" + ] + } + ], + "source": [ + "print(rts.calculateAverageHertzDay(\"2023-1-11\"))\n", + "print(rts.calculateAverageHertzMultiDay())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "runs = {\"run_1\" : {}}\n", + "runs[\"run_1\"][\"start\"] = dt.timestamp(dt.now())\n", + "runs[\"run_1\"][\"end\"] = dt.timestamp(dt.now() + td(0,3600))\n", + "\n", + "runs[\"run_2\"] = {}\n", + "runs[\"run_2\"][\"start\"] = dt.timestamp(dt.now() + td(0,3600) +td(0,3600))\n", + "\n", + "runs[\"run_2\"][\"end\"] = dt.timestamp(dt.now() + td(0,3600) +td(0,3600) + td(0,3600))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "total_time = 0\n", + "for key in list(runs.keys()):\n", + " total_time = runs[key][\"end\"] - runs[key][\"start\"] + total_time" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(total_time)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "today = dt.today()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "{str(today.year)+\"-\"+str(today.month)+\"-\"+str(today.day): {\"run_1\": {\"start\": dt.timestamp(dt.now()), \"end\": dt.timestamp(dt.now()), \"hz\": [56,60,57,61,59,57,60]}}}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "a = [1,2,4,5]\n", + "b = [6,7,8,8,89]\n", + "c = []\n", + "c += a\n", + "c += b\n", + "print(math.fsum(c)/len(c))\n", + "print((math.fsum(a)/len(a) + math.fsum(b)/len(b))/2)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'that': {'is': 'a bigger test'}}\n" + ] + } + ], + "source": [ + "t = {\"this\": \"test1\", \"that\": {\"is\": \"a bigger test\"}}\n", + "del t[\"this\"]\n", + "print(t)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "webkit", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.12" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "22238595996e71d7b27448e64f75d285aa95d1182295fdd30f75905446cf0091" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}