super un-efficient way to mangle data for graph
parent
8eb3a45e2e
commit
f4676c2257
64
app.py
64
app.py
|
@ -3,6 +3,8 @@ import json, requests
|
|||
from flask import Flask, request, session, render_template, redirect, url_for, Response, send_file
|
||||
from flask_session import Session
|
||||
|
||||
from tqdm import tqdm
|
||||
|
||||
from io import BytesIO
|
||||
|
||||
import logging
|
||||
|
@ -138,8 +140,11 @@ def camera_detail(esn=None):
|
|||
een = EagleEyev3(config)
|
||||
|
||||
camera = een.get_camera_by_id(esn)
|
||||
camera.get_list_of_events(end_timestamp=een.time_before(ts=een.time_now(), hours=0), \
|
||||
start_timestamp=een.time_before(ts=een.time_now(), hours=6) )
|
||||
now = een.time_now()
|
||||
|
||||
for i in tqdm(range(0,4)):
|
||||
camera.get_list_of_events(end_timestamp=een.time_before(ts=now, hours=6*i), \
|
||||
start_timestamp=een.time_before(ts=now, hours=6*(i+1)))
|
||||
|
||||
values = {
|
||||
"current_user": een.current_user,
|
||||
|
@ -149,7 +154,62 @@ def camera_detail(esn=None):
|
|||
|
||||
return render_template('camera_detail_partial.html', template_values=values)
|
||||
|
||||
@app.route('/camera/<esn>/status_plot')
|
||||
def camera_status_plot(esn=None):
|
||||
if 'een' in session:
|
||||
een = session['een']
|
||||
else:
|
||||
een = EagleEyev3(config)
|
||||
|
||||
cam = een.get_camera_by_id(esn)
|
||||
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
from matplotlib.figure import Figure
|
||||
import matplotlib.dates as mdates
|
||||
import base64
|
||||
|
||||
atm_df = pd.DataFrame(cam.events['status'][::-1], columns=['id', 'startTimestamp', 'actorId', 'data'])
|
||||
atm_df['ts'] = pd.to_datetime(atm_df.startTimestamp)
|
||||
atm_df['status_desc'] = atm_df['data'].apply(lambda x: x[0]['newStatus']['connectionStatus'])
|
||||
atm_df['status'] = atm_df['status_desc'].replace(to_replace=['online', 'offline', 'error', 'deviceOffline', 'deviceOnline', 'off', 'bridgeOffline'], value=[1,0,0,0,0,0,0])
|
||||
imp = atm_df.set_index(['ts'])
|
||||
|
||||
# Generate the figure **without using pyplot**.
|
||||
fig = Figure(figsize=(16, 12), dpi=80)
|
||||
ax = fig.subplots()
|
||||
|
||||
imp['startTimestamp'] = pd.to_datetime(imp['startTimestamp'])
|
||||
imp = imp.drop(['id', 'actorId', 'data', 'status_desc'], axis=1)
|
||||
data = imp.resample('S').bfill()
|
||||
data['status'] = data['status'].astype('int64')
|
||||
|
||||
print(len(data))
|
||||
print(data.info())
|
||||
print(data)
|
||||
|
||||
data = data.drop(['startTimestamp'], axis=1)
|
||||
|
||||
print(data)
|
||||
|
||||
ax.step(data.index, data['status'], lw=5, color='blue')
|
||||
# ax.fill_between(data['startTimestamp'], data['status'])
|
||||
ax.axhline(1, color='green', lw=2, alpha=0.3)
|
||||
ax.axhline(0, color='red', lw=2, alpha=0.3)
|
||||
# ax.set_title('Manual DateFormatter', loc='left', y=0.85, x=0.02, ontsize='medium')
|
||||
# Text in the x-axis will be displayed in 'YYYY-mm' format.
|
||||
# ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%b'))
|
||||
# Rotates and right-aligns the x labels so they don't crowd each other.
|
||||
for label in ax.get_xticklabels(which='major'):
|
||||
label.set(rotation=30, horizontalalignment='right')
|
||||
|
||||
|
||||
# Save it to a temporary buffer.
|
||||
buf = BytesIO()
|
||||
fig.savefig(buf, format="png")
|
||||
# Embed the result in the html output.
|
||||
data = base64.b64encode(buf.getbuffer()).decode("ascii")
|
||||
return f"<div class='col-md-12'><img src='data:image/png;base64,{data}' width=100%/></div>"
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -15,3 +15,5 @@ gunicorn==20.1.0
|
|||
cachelib==0.10.2
|
||||
Flask-Session==0.5.0
|
||||
EagleEyev3>=0.0.4
|
||||
tqdm
|
||||
|
||||
|
|
|
@ -11,14 +11,20 @@
|
|||
<ul>
|
||||
{% if template_values['events'] %}
|
||||
{% for event in template_values['events'] %}
|
||||
<li>{{ event['data'][0]['newStatus']['connectionStatus'] }} <br> <small>{{ event['startTimestamp'] }}</small></li>
|
||||
<li>
|
||||
{{ event['data'][0]['newStatus']['connectionStatus'] }}
|
||||
<br> <small>{{ event['endTimestamp'] }}</small>
|
||||
<br> <small>{{ event['startTimestamp'] }}</small>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<li>No events in the last six hours</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
<div>
|
||||
<!-- <button hx-get="/camera/{{ template_values['camera'].id }}/events" hx-trigger="click" hx-target="#event_list">refresh</button> -->
|
||||
<button hx-get="/camera/{{ template_values['camera'].id }}/status_plot" hx-trigger="click" hx-target="#camera_status_plot">
|
||||
load plot
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<h3>Offline</h3>
|
||||
<ul>
|
||||
{% for camera in template_values['cameras'] %}
|
||||
{% if camera.is_offline() %}
|
||||
{% if camera.is_offline() and camera.bridge_id %}
|
||||
<li hx-get="/camera/{{ camera.id }}" hx-trigger="click" hx-target="#camera_detail"> {{ camera.name }}</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
{% include 'cameras_partial.html' %}
|
||||
</div>
|
||||
|
||||
<div class="row" id="camera_status_plot">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
|
Loading…
Reference in New Issue