EE-status-v3/app.py

220 lines
6.1 KiB
Python
Raw Normal View History

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
logger = logging.getLogger()
#logger.setLevel('DEBUG')
logger.setLevel('INFO')
#logger.setLevel('WARN')
#logger.setLevel('ERROR')
#logger.setLevel('CRITICAL')
from EagleEyev3 import *
from settings import config
logging.info(f"Using EagleEyev3 version {EagleEyev3.__version__}")
app = Flask(__name__)
SESSION_TYPE = 'filesystem'
app.config.from_object(__name__)
Session(app)
@app.route('/')
def index():
if 'een' in session:
een = session['een']
else:
een = EagleEyev3(config)
session['een'] = een
# using current_user as a proxy for an established valid session
if een.access_token == None:
base_url = "https://auth.eagleeyenetworks.com/oauth2/authorize"
path_url = f"?client_id={een.client_id}&response_type=code&scope=vms.all&redirect_uri={een.redirect_uri}"
return redirect(f"{base_url}{path_url}")
# call this to check if session is actually valid
check = een.get_current_user()
if 'success' not in check or check['success'] == False:
base_url = "https://auth.eagleeyenetworks.com/oauth2/authorize"
path_url = f"?client_id={een.client_id}&response_type=code&scope=vms.all&redirect_uri={een.redirect_uri}"
return redirect(f"{base_url}{path_url}")
else:
logging.info(f"{check['success']} - check get_current_user {een.current_user['email']} {een.access_token}")
#logging.info(een.cameras)
# this call could get expensive
een.get_list_of_cameras()
#logging.info(een.cameras)
values = {
"current_user": een.current_user,
"cameras": een.cameras
}
return render_template('index.html', template_values=values)
@app.route('/login_callback')
def login_callback():
# This is getting the ?code= querystring value from the HTTP request.
code = request.args.get('code')
if 'een' in session:
een = session['een']
else:
een = EagleEyev3(config)
if (code):
# use the include code parameter to complete login process
oauth_object = een.login_tokens(code)
return redirect(url_for('index'))
@app.route('/logout')
def logout():
if 'een' in session:
een = session['een']
een.logout()
session.pop('een')
return redirect(url_for('index'))
@app.route('/cameras')
def cameras():
if 'een' in session:
een = session['een']
else:
een = EagleEyev3(config)
een.get_list_of_cameras()
values = {
"current_user": een.current_user,
"cameras": een.cameras
}
return render_template('cameras_partial.html', template_values=values)
@app.route('/camera/<esn>/live_preview')
def camera_live_preivew(esn=None):
if 'een' in session:
een = session['een']
else:
een = EagleEyev3(config)
camera = een.get_camera_by_id(esn)
res = camera.get_live_preview()
if res:
return send_file(BytesIO(res.content), mimetype='image/jpeg')
else:
2023-07-14 15:48:14 +00:00
return send_file('static/placeholder.png')
@app.route('/camera/<esn>')
def camera_detail(esn=None):
if 'een' in session:
een = session['een']
else:
een = EagleEyev3(config)
camera = een.get_camera_by_id(esn)
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,
"camera": camera,
2023-07-14 13:26:06 +00:00
"events": camera.events['status']
}
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>"
if __name__ == '__main__':
app.run(host=een.server_host, port=een.server_port)