import requests import matplotlib.pyplot as plt from datetime import datetime import json import os latest_history_path = "latest_history.json" file_path = latest_history_path history_url = "http://192.168.178.84:9587/bettwaage/history" focus_on_latest_bed_data = False convert_time_to_seconds = True # Get data data = None if file_path is None or not os.path.exists(file_path): print("Fetching data ...") data = requests.get(history_url) data = data.json() print("Saving latest data ...") with open(latest_history_path, "w", encoding="UTF-8") as fp: json.dump(data, fp) else: print("Reading data ...") with open(file_path, "r") as fp: data = json.load(fp) print("Processing data ...") # Get rough value for empty bed weight per leg rough_bed_weight = 80 bed_only_weight = {} for d in data: if d["total"] < rough_bed_weight: bed_only_weight = { "tl": d["tl"], "tr": d["tr"], "bl": d["bl"], "br": d["br"], } total_bed_only_weight = sum(bed_only_weight.values()) break if focus_on_latest_bed_data: # Collect all coherent sequences of someone being in bed in_bed_datas: list[list[dict]] = [] is_in_bed_sequence = False threshhold = 100.0 for d in data: t = d["total"] if t >= threshhold: if not is_in_bed_sequence: in_bed_datas.append([]) is_in_bed_sequence = True in_bed_datas[-1].append(d) elif is_in_bed_sequence: is_in_bed_sequence = False # Pick latest with minimum length/duration min_length = 100 for sequence in in_bed_datas: if len(sequence) >= min_length: data = sequence # Prepare data for plotting x = [d["timestamp"] for d in data] # x = [datetime.strptime(d, "%Y-%m-%d %H:%M:%S.%f") for d in x] # if convert_time_to_seconds: # max_time = max(x) # x = [(d - max_time).total_seconds() for d in x] total = [d["total"] for d in data] tl = [d["tl"] for d in data] tr = [d["tr"] for d in data] bl = [d["bl"] for d in data] br = [d["br"] for d in data] top = [l + r for l, r in zip(tl, tr)] bottom = [l + r for l, r in zip(bl, br)] left = [t + b for t, b in zip(tl, bl)] right = [t + b for t, b in zip(tr, br)] fig, ax = plt.subplots() person_weight = [t - total_bed_only_weight for t in total] ax.set_xlabel("Time (s)") ax.set_ylabel("Weight (kg)") ax.plot(x, person_weight, color="tab:blue") plt.show() exit() # Experiment: Calculate position over time bed_size = (140, 200) left_bed_only = bed_only_weight["tl"] + bed_only_weight["bl"] top_bed_only = bed_only_weight["tr"] + bed_only_weight["tl"] right_bed_only = bed_only_weight["tr"] + bed_only_weight["br"] bottom_bed_only = bed_only_weight["br"] + bed_only_weight["bl"] position_over_time = [] for t, b, l, r in zip(top, bottom, left, right): horizontal_weight = l - left_bed_only + r - right_bed_only vertical_weight = t - top_bed_only + b - bottom_bed_only position_over_time.append( ( bed_size[0] * (l - left_bed_only) / horizontal_weight, bed_size[1] * (t - top_bed_only) / vertical_weight, ) ) # Plot data fig, (ax0, ax1) = plt.subplots(nrows=2) ax0.set_xlabel("Time (s)") ax0.set_ylabel("Weight (kg)") ax0.plot(x, total, color="tab:blue") ax0.plot(x, tl, color="tab:red") ax0.plot(x, tr, color="tab:green") ax0.plot(x, bl, color="tab:orange") ax0.plot(x, br, color="tab:purple") ax0.plot(x, top, color="tab:pink") ax0.plot(x, bottom, color="tab:grey") ax0.legend( ["Total", "Top Left", "Top Right", "Bottom Left", "Bottom Right", "Top", "Bottom"] ) # Experiment: Plot position import math import colorsys segments = 100 seg_length = math.ceil(len(position_over_time) / segments) horizontal, vertical = zip(*position_over_time) for i in range(0, segments): low = int(i * seg_length) high = min(int((i + 1) * seg_length), len(position_over_time)) ax1.plot( horizontal[low:high], vertical[low:high], color=colorsys.hsv_to_rgb(i / segments * 0.5, 1, 0.7), linewidth=0.3, ) ax1.set_xlim((0, bed_size[0])) ax1.set_ylim((0, bed_size[1])) ax1.invert_yaxis() plt.show()