157 lines
4.1 KiB
Python
157 lines
4.1 KiB
Python
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()
|