Commit ed54eafd authored by Larkin Heintzman's avatar Larkin Heintzman

plotting updates

parent 768b2405
......@@ -27,6 +27,10 @@ https://abhishekbose550.medium.com/deep-learning-for-production-deploying-yolo-u
start docker registry: "docker run -d -p 5000:5000 --name registry registry:2.7"
then build and tag images "docker tag <orig>:latest localhost:5000/<orig>:latest" and follow with "docker push localhost:5000/<orig>:latest" then kubernetes should be able to find the image
test darknet: ./darknet detector test cfg/coco.data cfg/yolov3.cfg yolov3.weights -ext_output shopping-crowded-mall-17889570.jpg
https://blog.roboflow.com/how-to-train-scaled-yolov4/
-->
## Image building
......
......@@ -15,12 +15,21 @@ INTERFACE="enp8s0" # laptop interface
# JINTERFACE="wlan0" # jetson interface
JINTERFACE="eth0" # jetson interface
LOOPINTERFACE="lo" # loopback interface for bgp
echo "Using interface: $INTERFACE"
echo "Using jetson interface: $JINTERFACE"
echo "And load-balancer IP: $VIP"
sudo swapoff -a # turn off swap memory
# put load balancer pod spec in the manifests directory
# sudo docker run --network host --rm ghcr.io/kube-vip/kube-vip:main manifest pod \
# --vip "$VIP" \
# --interface "$INTERFACE" \
# --arp \
# --controlplane \
# --leaderElection | sudo tee /etc/kubernetes/manifests/vip.yaml
sudo docker run --network host --rm ghcr.io/kube-vip/kube-vip:main manifest pod \
--vip "$VIP" \
--interface "$INTERFACE" \
......@@ -28,11 +37,13 @@ sudo docker run --network host --rm ghcr.io/kube-vip/kube-vip:main manifest pod
--controlplane \
--leaderElection | sudo tee /etc/kubernetes/manifests/vip.yaml
sudo sed -i 's/imagePullPolicy: Always/imagePullPolicy: IfNotPresent/g' /etc/kubernetes/manifests/vip.yaml
# load up endpoint in the config file
configFile="kubeadm-config.yaml"
newIP="$VIP"
key="controlPlaneEndpoint"
sed -r "s/^(\s*${key}\s*:\s*).*/\1"${newIP}:6443"/" -i "$configFile"
# configFile="kubeadm-config.yaml"
# newIP="$VIP"
# key="controlPlaneEndpoint"
# sed -r "s/^(\s*${key}\s*:\s*).*/\1"${newIP}:6443"/" -i "$configFile"
# key1="apiServer"
# key2="advertiseAddress"
......@@ -56,24 +67,30 @@ sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectl apply -f flannel.yml
# create control-plane join command and copy it to clip
OLDIFS=$IFS
IFS=''
ifCMD="ip route get 8.8.8.8 | awk -F'dev ' 'NR==1{split(\$2,a,\" \");print a[1]}'"
vipCMD="sudo docker run --network host --rm ghcr.io/kube-vip/kube-vip:main manifest pod --vip "$VIP" \
--interface "$JINTERFACE" \
--arp \
--controlplane \
--leaderElection | sudo tee /etc/kubernetes/manifests/vip.yaml"
# OLDIFS=$IFS
# IFS=''
# # ifCMD="ip route get 8.8.8.8 | awk -F'dev ' 'NR==1{split(\$2,a,\" \");print a[1]}'"
# # vipCMD="sudo docker run --network host --rm ghcr.io/kube-vip/kube-vip:main manifest pod --vip "$VIP" \
# # --interface "$JINTERFACE" \
# # --arp \
# # --controlplane \
# # --leaderElection | sudo tee /etc/kubernetes/manifests/vip.yaml"
#
# # echo $(/bin/bash -c "$ifCMD")
# # echo $(/bin/bash -c "$vipCMD")
# IFS=$OLDIFS
# echo $(/bin/bash -c "$ifCMD")
# echo $(/bin/bash -c "$vipCMD")
IFS=$OLDIFS
# newKey=$(sudo kubeadm init phase upload-certs --upload-certs | sed -n '3~0p')
echo "sudo $(kubeadm token create --print-join-command)" | xclip -sel clip
# echo "sudo swapoff -a && sudo $(kubeadm token create --print-join-
echo "------------------------------------------"
newKey=$(sudo kubeadm init phase upload-certs --upload-certs | sed -n '3~0p')
# was working here
echo "$vipCMD && sudo $(kubeadm token create --print-join-command) --control-plane --certificate-key $newKey" | xclip -sel clip
# the following is for a highly-available kubernetes cluster, do NOT fuck with it. it will break first your mind then your soul
# echo "------------------------------------------"
# newKey=$(sudo kubeadm init phase upload-certs --upload-certs | sed -n '3~0p')
# echo "sudo swapoff -a && $vipCMD && sudo sed -i 's/imagePullPolicy: Always/imagePullPolicy: IfNotPresent/g' /etc/kubernetes/manifests/vip.yaml && sudo $(kubeadm token create --print-join-command) --control-plane --certificate-key $newKey -v=9" | xclip -sel clip
# # echo "sudo swapoff -a && sudo $(kubeadm token create --print-join-command) --control-plane --certificate-key $newKey" | xclip -sel clip
echo "..."
echo "Done starting cluster, control-plane join command is copied to clipboard."
......
# FROM alpine:3
FROM bash:latest
RUN apk update && apk upgrade && apk add --no-cache jq
# FROM bash:latest
FROM ros:noetic
RUN apt update && apt install -y jq iputils-ping nano
RUN sed -e '/set -e/ s/^#*/#/' -i ros_entrypoint.sh
COPY ping.sh /
# health check runs grep command every 10 seconds and registers container as unhealthy if it takes longer than 3 seconds or ping is not running
HEALTHCHECK --interval=10s --timeout=3s --start-period=5s \
CMD ps aux | grep '[s]h ping' || exit 1
# HEALTHCHECK --interval=10s --timeout=3s --start-period=5s \
# CMD ps aux | grep '[s]h ping' || exit 1
#!/usr/local/bin/bash
#!/usr/bin/bash
# endpoints=192.168.1.5
# interface=wlp0s20f3
# filename="/home/llh/ros-kubernetes/docker/pinger/pingStats.json"
# gpstopic="/dji_osdk_ros/gps_position"
echo "pinging: $endpoints"
echo "through: $interface"
echo "save to: $filename"
echo "gps topic: $gpstopic"
echo " "
if test -f "$filename"; then
......@@ -12,14 +18,8 @@ else
echo "{}" > "$filename"
fi
# if [[ -n "$nfsFilename" ]]; then
# if test -f "$nfsFilename"; then
# echo "NFS file $nfsFilename already exists."
# else
# touch "$nfsFilename"
# echo "{}" > "$nfsFilename"
# fi
# fi
# enable ros commands
source /ros_entrypoint.sh
echo ping "${endpoints} every ${downtime:=3} sec, saving to ${filename}"
# for endpoints in "${endpoints[@]}"; do
......@@ -54,13 +54,38 @@ while true; do
echo "{}" > "$filename"
fi
# keep a diary
# get gps data if present (timeout 5s)
gpsData=$(timeout 5 rostopic echo -n 1 $gpstopic | grep "latitude:\|longitude:\|altitude:")
gpsData=$(echo $gpsData | tr '\n' ' ')
OLDIFS=$IFS
IFS=" "
read trash1 latitude trash2 longitude trash3 altitude <<< "$gpsData"
IFS=$OLDIFS
echo $latitude
echo $longitude
echo $altitude
echo "------------------"
# ping can return standard deviation and gps data may not be available
if [[ -z "$latitude" ]]; then
# echo "gps data is not there"
if [[ -n "$num4" ]]; then
jq --arg timedate $(date +"%H:%M_%F") --arg target $endpoints --argjson rttMin $num1 --argjson rttAvg $num2 --argjson rttMax $num3 --argjson stdDev $num4 '.[$target][$timedate] += [{"min":$rttMin,"avg":$rttAvg,"max":$rttMax,"std":$stdDev}]' "$filename" > "$filename.tmp" && mv "$filename.tmp" "$filename"
else
jq --arg timedate $(date +"%H:%M_%F") --arg target $endpoints --argjson rttMin $num1 --argjson rttAvg $num2 --argjson rttMax $num3 '.[$target][$timedate] += [{"min":$rttMin,"avg":$rttAvg,"max":$rttMax}]' "$filename" > "$filename.tmp" && mv "$filename.tmp" "$filename"
fi
else
echo "gps data IS there"
echo $latitude
echo $longitude
echo $altitude
if [[ -n "$num4" ]]; then
jq --arg timedate $(date +"%H:%M_%F") --arg target $endpoints --argjson altitude $altitude --argjson longitude $longitude --argjson latitude $latitude --argjson rttMin $num1 --argjson rttAvg $num2 --argjson rttMax $num3 --argjson stdDev $num4 '.[$target][$timedate] += [{"lat":$latitude,"long":$longitude,"alt":$altitude,"min":$rttMin,"avg":$rttAvg,"max":$rttMax,"std":$stdDev}]' "$filename" > "$filename.tmp" && mv "$filename.tmp" "$filename"
else
jq --arg timedate $(date +"%H:%M_%F") --arg target $endpoints --argjson altitude $altitude --argjson longitude $longitude --argjson latitude $latitude --argjson rttMin $num1 --argjson rttAvg $num2 --argjson rttMax $num3 '.[$target][$timedate] += [{"lat":$latitude,"long":$longitude,"alt":$altitude,"min":$rttMin,"avg":$rttAvg,"max":$rttMax}]' "$filename" > "$filename.tmp" && mv "$filename.tmp" "$filename"
fi
fi
sleep ${downtime:=3}
done
......
# kubeadm-config.yaml
# apiVersion: kubeadm.k8s.io/v1beta3
# kind: InitConfiguration
# localAPIEndpoint:
# advertiseAddress: 192.168.111.200
# bindPort: 6443
# ---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: v1.24.0
# gets set by startup
controlPlaneEndpoint: 192.168.111.25:6443
kind: ClusterConfiguration
# controlPlaneEndpoint: 192.168.111.25:6443
controlPlaneEndpoint: 192.168.111.200:6443
networking:
podSubnet: "10.244.0.0/16"
# api:
# advertiseAddress: "192.168.1.233"
# bindPort: 6443
# apiServerCertSANs:
# - "192.168.1.233"
# podSubnet: "192.168.222.0/16"
---
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
cgroupDriver: systemd
# resolvConf: /etc/resolv.conf
......@@ -40,18 +40,29 @@ spec:
volumeMounts:
- name: ping-storage
mountPath: /tmp/pingStats
image: localhost:5000/doorbell:latest
imagePullPolicy: Always
command: ["/usr/local/bin/bash"]
args: ["-c", "/ping.sh & while true; do sleep 10; done;"]
image: doorbell
imagePullPolicy: IfNotPresent
command: ["/bin/bash"]
args: ["-c", "/ping.sh"]
env:
- name: endpoints
value: "192.168.111.200"
- name: interface
value: "eth0" # not strictly necessary
- name: filename
value: "/tmp/pingStats/pingStats.json"
value: "/tmp/pingStats/pingStatsKubernetes.json"
- name: downtime # time to wait between pings
value: "1"
- name: gpstopic
value: "/rossettiModem/dji_sdk/gps_position"
- name: ROS_IP
value: "192.168.111.202"
- name: ROS_MASTER_URI
value: "http://192.168.111.200:11311"
ports:
- containerPort: 11311
name: pingport
nodeSelector:
kubernetes.io/hostname: neruda # to run on control plane
kubernetes.io/hostname: rossetti
# kubernetes.io/hostname: neruda
# kubernetes.io/hostname: sentinel
opencv docker container install steps:
- starting with: https://funvision.blogspot.com/2017/10/opencv-docker-ubuntu-image.html
- apt-get install build-essential
- apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
- then we need to add an old repo because jasper got removed recently: ... well that failed because obviously going back to an old distro to install a package was stupid.
- trying:
apt-get install opencv-data
apt-get install libopencv-dev
-> yAS
but we need DEBIAN_FRONTEND="noninteractive" and apt-get install --yes
# api key from gurgle AIzaSyDDFrIPAMv3HS6PXTDcWfiUys8si_-yZ-c
import numpy as np
from gmplot import GoogleMapPlotter
from random import random
import json
from pprint import PrettyPrinter
import matplotlib.pyplot as plt
import matplotlib
from matplotlib.ticker import FormatStrFormatter
import shutil
import requests
def rgb_to_hex(rgb):
return '%02x%02x%02x' % rgb
def getMapImage(bbox=[38.865,-77.072,38.876,-77.001], apiKey="GKvj5HV6DLjqJT8awam4KQL3d26GP1M1", mapType="sat", mapSize=[600,400]):
req = "https://www.mapquestapi.com/staticmap/v5/map?key={}&boundingBox={}&type={}&size={}".format(apiKey,','.join(map(str,bbox)),mapType,','.join(map(str,mapSize)))
response = requests.get(req, stream=True)
with open('mapImg.jpeg', 'wb') as out_file:
shutil.copyfileobj(response.raw, out_file)
del response
def inflateBounds(bbox=[38.865,-77.072,38.876,-77.001], amt=0.001):
return [bbox[0]-amt, bbox[1]-amt, bbox[2]+amt, bbox[3]+amt]
filenames = ["/home/llh/ros-kubernetes/plottingTools/pingStats_may_29th_2022/pingStats.json",
"/home/llh/ros-kubernetes/plottingTools/pingStats_may_29th_2022/pingStatsDocker.json"]
lats = []
longs = []
avgLatencies = []
maxAvgLatency = 0.0
realBox = [1000.0,1000.0,-1000.0,-1000.0] # (min_long, max_long, min_lat, max_lat)
# potentially the least python-ish way to handle this
for (i, fn) in enumerate(filenames):
with open(fn) as file:
data = json.load(file)
# need to iterate over endpoints as well
endpoint = "192.168.111.200"
# ignore time stamps for now
# and figure out center of test area
timelessData = []
for minuteData in data[endpoint].values():
for pt in minuteData:
if ("lat" in pt):
timelessData.append(pt)
lats.append([dataPoint["lat"] for dataPoint in timelessData])
longs.append([dataPoint["long"] for dataPoint in timelessData])
avgLatencies.append([dataPoint["avg"] for dataPoint in timelessData])
maxAvgLatency = np.max(avgLatencies[i] + [maxAvgLatency])
realBox[0] = np.min([dataPoint["lat"] for dataPoint in timelessData] + [realBox[0]])
realBox[1] = np.min([dataPoint["long"] for dataPoint in timelessData] + [realBox[1]])
realBox[2] = np.max([dataPoint["lat"] for dataPoint in timelessData] + [realBox[2]])
realBox[3] = np.max([dataPoint["long"] for dataPoint in timelessData] + [realBox[3]])
print(realBox)
bigBox = inflateBounds(realBox, 0.0002)
sqrAspect = (bigBox[1] - bigBox[3])/(bigBox[0] - bigBox[2])
getMapImage(bbox=bigBox, mapType="sat", mapSize=[1000,1000])
plt.ticklabel_format(style='plain') # to prevent scientific notation
plt.ticklabel_format(useOffset=False)
fig, ax = plt.subplots()
ax.yaxis.set_major_formatter(FormatStrFormatter('%.2f'))
ax.xaxis.set_major_formatter(FormatStrFormatter('%.2f'))
mapPlot = plt.imread('mapImg.jpeg')
for i in range(len(lats)):
# get latency coloring
if i == 0:
latencyColor = [((maxAvgLatency-val*0.7)/maxAvgLatency,0.0,0.0) for val in avgLatencies[i]]
if i == 1:
latencyColor = [(0.0,(maxAvgLatency-val*0.7)/maxAvgLatency,0.0) for val in avgLatencies[i]]
else:
latencyColor = [(0.0,0.0,(maxAvgLatency-val*0.7)/maxAvgLatency) for val in avgLatencies[i]]
latencySize = [20*(siz/maxAvgLatency) + 5 for siz in avgLatencies[i]]
plt.scatter(longs[i], lats[i], zorder=1, alpha=1, c=latencyColor, s=latencySize, label=[f.split('/') for f in filenames][i][-1])
plt.imshow(mapPlot, zorder=0, extent=[bigBox[1], bigBox[3], bigBox[0], bigBox[2]], aspect='equal')
plt.title('Network latency visualized')
plt.xlim(realBox[1],realBox[3])
plt.ylim(realBox[0],realBox[2])
plt.xticks(np.linspace(bigBox[1], bigBox[3], 3))
plt.yticks(np.linspace(bigBox[0], bigBox[2], 3))
plt.legend()
print(sqrAspect)
# plt.show()
plt.savefig("plottedMap.jpeg", dpi=400)
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
{
"192.168.111.200": {
"05:23_2022-01-10": [
{
"lat": 37.19703455310033,
"long": -80.57814568498682,
"alt": 453.06365966796875,
"min": 12.727,
"avg": 14.155,
"max": 15.089,
"std": 1.025
},
{
"lat": 37.197036689215,
"long": -80.57814645267614,
"alt": 453.0914611816406,
"min": 12.997,
"avg": 22.964,
"max": 33.591,
"std": 8.42
},
{
"lat": 37.19703877931635,
"long": -80.57814934429226,
"alt": 453.12225341796875,
"min": 12.704,
"avg": 14.437,
"max": 17.093,
"std": 1.906
},
{
"lat": 37.196961096688334,
"long": -80.57837534935616,
"alt": 454.3573303222656,
"min": 15.034,
"avg": 17.341,
"max": 20.452,
"std": 2.283
}
],
"05:24_2022-01-10": [
{
"lat": 37.196958347425415,
"long": -80.57837539671705,
"alt": 452.5787353515625,
"min": 14.885,
"avg": 15.306,
"max": 15.65,
"std": 0.317
},
{
"lat": 37.19695475089611,
"long": -80.57837558433236,
"alt": 452.5632019042969,
"min": 14.739,
"avg": 31.79,
"max": 48.842,
"std": 17.051
},
{
"lat": 37.19694877286517,
"long": -80.57837578650063,
"alt": 452.568603515625,
"min": 13.661,
"avg": 20.475,
"max": 27.289,
"std": 6.814
},
{
"lat": 37.19694763413663,
"long": -80.5783751699529,
"alt": 452.568603515625,
"min": 14.825,
"avg": 23.361,
"max": 28.649,
"std": 6.093
},
{
"lat": 37.196947017324376,
"long": -80.57837445538193,
"alt": 452.57342529296875,
"min": 14.074,
"avg": 16.824,
"max": 21.021,
"std": 3.015
},
{
"lat": 37.19694568152154,
"long": -80.57837429132067,
"alt": 452.6016540527344,
"min": 13.19,
"avg": 20.858,
"max": 32.065,
"std": 8.101
}
],
"05:25_2022-01-10": [
{
"lat": 37.196945574878,
"long": -80.57837516086572,
"alt": 452.6947326660156,
"min": 13.933,
"avg": 21.16,
"max": 34.872,
"std": 9.7
},
{
"lat": 37.196947766604026,
"long": -80.578376833735,
"alt": 452.7162780761719,
"min": 14.302,
"avg": 14.978,
"max": 15.987,
"std": 0.726
},
{
"lat": 37.196950075330506,
"long": -80.57837467988637,
"alt": 452.7153625488281,
"min": 14.399,
"avg": 21.925,
"max": 29.452,
"std": 7.526
},
{
"lat": 37.19695215108527,
"long": -80.57837503129947,
"alt": 452.72283935546875,
"min": 14.465,
"avg": 15.099,
"max": 15.518,
"std": 0.455
},
{
"lat": 37.19695281414207,
"long": -80.57837566722198,
"alt": 452.716796875,
"min": 14.233,
"avg": 22.284,
"max": 31.544,
"std": 7.118
}
],
"05:26_2022-01-10": [
{
"lat": 37.196954363482774,
"long": -80.57837490135145,
"alt": 452.7495422363281,
"min": 13.123,
"avg": 14.317,
"max": 15.402,
"std": 0.933
},
{
"lat": 37.19705516345618,
"long": -80.57807292349135,
"alt": 495.4686584472656,
"min": 14.839,
"avg": 15.287,
"max": 15.996,
"std": 0.507
},
{
"lat": 37.19705778031357,
"long": -80.57807198836132,
"alt": 496.10546875,
"min": 14.256,
"avg": 15.096,
"max": 16.117,
"std": 0.77
},
{
"lat": 37.19779795981652,
"long": -80.57798985504684,
"alt": 497.03271484375,
"min": 13.519,
"avg": 32.645,
"max": 59.701,
"std": 19.669
},
{
"lat": 37.19710323280406,
"long": -80.57735325238846,
"alt": 496.07952880859375,
"min": 14.917,
"avg": 15.091,
"max": 15.265,
"std": 0.174
},
{
"lat": 37.19724335272374,
"long": -80.577034457663,
"alt": 496.5080261230469,
"min": 14.529,
"avg": 14.953,
"max": 15.498,
"std": 0.404
}
],
"05:27_2022-01-10": [
{
"lat": 37.1975313778021,
"long": -80.57702838480242,
"alt": 496.5955810546875,
"min": 14.721,
"avg": 15.207,
"max": 15.677,
"std": 0.39
},
{
"lat": 37.19787404780704,
"long": -80.57680489229688,
"alt": 496.57049560546875,
"min": 15.639,
"avg": 21.565,
"max": 26.648,
"std": 4.533
},
{
"lat": 37.19804232063131,
"long": -80.57669643252781,
"alt": 496.6546630859375,
"min": 13.852,
"avg": 14.43,
"max": 15.37,
"std": 0.67
},
{
"lat": 37.19772697904325,
"long": -80.5770454442686,
"alt": 496.8408203125,
"min": 12.592,
"avg": 13.209,
"max": 13.826,
"std": 0.617
},
{
"lat": 37.197320775803846,
"long": -80.57764520541079,
"alt": 484.6840515136719,
"min": 15.311,
"avg": 18.126,
"max": 20.942,
"std": 2.815
},
{
"lat": 37.19697810863891,
"long": -80.57831185561668,
"alt": 452.6222229003906,
"min": 16.089,
"avg": 33.024,
"max": 49.96,
"std": 16.935
}
],
"05:28_2022-01-10": [
{
"lat": 37.196979074384366,
"long": -80.57830769844665,
"alt": 451.330078125,
"min": 13.864,
"avg": 17.702,
"max": 21.54,
"std": 3.838
},
{
"lat": 37.196976985950535,
"long": -80.57830557177756,
"alt": 451.3295593261719,
"min": 13.009,
"avg": 16.344,
"max": 21.833,
"std": 3.91
},
{
"lat": 37.196975308522944,
"long": -80.57830415577975,
"alt": 451.3286437988281,
"min": 14.521,
"avg": 17.74,
"max": 24.035,
"std": 4.451
},
{
"lat": 37.19697392936116,
"long": -80.57830460670286,
"alt": 451.36322021484375,
"min": 14.28,
"avg": 14.856,
"max": 15.747,
"std": 0.638
},
{
"lat": 37.19697282650723,
"long": -80.57830317042826,
"alt": 451.3707275390625,
"min": 15.08,
"avg": 15.537,
"max": 16.164,
"std": 0.458
}
],
"05:29_2022-01-10": [
{
"lat": 37.19697340995266,
"long": -80.57830267877954,
"alt": 451.375244140625,
"min": 14.455,
"avg": 16.149,
"max": 17.631,
"std": 1.305
},
{
"lat": 37.196974324167634,
"long": -80.5783022709802,
"alt": 451.36737060546875,
"min": 15.24,
"avg": 18.919,
"max": 25.997,
"std": 5.006
},
{
"lat": 37.196975020125514,
"long": -80.57830335829631,
"alt": 451.41864013671875,
"min": 12.96,
"avg": 14.009,
"max": 14.98,
"std": 0.826
},
{
"lat": 37.19697379239599,
"long": -80.57830354899805,
"alt": 451.42034912109375,
"min": 14.571,
"avg": 15.491,
"max": 16.261,
"std": 0.698
},
{
"lat": 37.19697497482871,
"long": -80.57830373798453,
"alt": 451.42083740234375,
"min": 14.511,
"avg": 14.808,
"max": 15.148,
"std": 0.261
},
{
"lat": 37.196975482010856,
"long": -80.5783041758092,
"alt": 451.412841796875,
"min": 14.751,
"avg": 14.833,
"max": 14.88,
"std": 0.058
}
],
"05:30_2022-01-10": [
{
"lat": 37.19697425178656,
"long": -80.5783028373804,
"alt": 451.4086608886719,
"min": 15.143,
"avg": 36.555,
"max": 64.276,
"std": 20.548
},
{
"lat": 37.19697439192393,
"long": -80.5783021073303,
"alt": 451.4195861816406,
"min": 18.344,
"avg": 30.016,
"max": 44.63,
"std": 10.93
},
{
"lat": 37.19697381759779,
"long": -80.57830181409399,
"alt": 451.4179992675781,
"min": 13.693,
"avg": 17.304,
"max": 23.811,
"std": 4.61
},
{
"lat": 37.19697462049233,
"long": -80.57830301008524,
"alt": 451.43072509765625,
"min": 16.823,
"avg": 44.05,
"max": 62.353,
"std": 19.629
}
]
}
}
{
"192.168.111.200": {
"15:17_2022-05-29": [
{
"min": 14.019,
"avg": 25.007,
"max": 46.818,
"std": 15.422
},
{
"min": 14.195,
"avg": 18.927,
"max": 27.236,
"std": 5.894
},
{
"min": 12.568,
"avg": 13.834,
"max": 14.585,
"std": 0.9
}
],
"15:18_2022-05-29": [
{
"min": 13.465,
"avg": 124.664,
"max": 218.968,
"std": 84.742
},
{
"min": 13.566,
"avg": 13.816,
"max": 14.133,
"std": 0.236
},
{
"min": 13.581,
"avg": 13.776,
"max": 14.167,
"std": 0.276
}
],
"15:19_2022-05-29": [
{
"lat": 37.19727999999999,
"long": -80.577791,
"alt": 100.0999984741211,
"min": 15.273,
"avg": 125.15,
"max": 235.027,
"std": 109.877
},
{
"lat": 37.19727999999999,
"long": -80.577791,
"alt": 100.0999984741211,
"min": 13.945,
"avg": 14.194,
"max": 14.352,
"std": 0.178
},
{
"lat": 37.19727999999999,
"long": -80.577791,
"alt": 100.0999984741211,
"min": 13.549,
"avg": 17.37,
"max": 24.161,
"std": 4.814
}
]
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment