2019-11-03 16:38:01 +01:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
import dash
|
2019-11-14 00:50:53 +01:00
|
|
|
import dash_bootstrap_components as dbc
|
2019-11-03 16:38:01 +01:00
|
|
|
import dash_core_components as dcc
|
|
|
|
import dash_html_components as html
|
|
|
|
from dash.dependencies import Input, Output
|
|
|
|
import time
|
|
|
|
import requests
|
2020-02-10 15:46:41 +01:00
|
|
|
from math import log, log10
|
2019-11-03 16:38:01 +01:00
|
|
|
|
2019-11-10 20:59:08 +01:00
|
|
|
URL_BASE="http://innocence:5000"
|
|
|
|
|
2019-11-14 00:50:53 +01:00
|
|
|
def get_sensors():
|
|
|
|
ret = {}
|
|
|
|
try:
|
2020-02-10 16:05:18 +01:00
|
|
|
url = f"{URL_BASE}/sensor/get"
|
2019-11-14 00:50:53 +01:00
|
|
|
res = requests.get(url)
|
|
|
|
ret = res.json()
|
|
|
|
except Exception as ex:
|
2020-02-10 16:05:18 +01:00
|
|
|
print(f"Exception Type: {type(ex).__name__}, args:\n{ex.args}")
|
|
|
|
|
2019-11-14 00:50:53 +01:00
|
|
|
return ret
|
|
|
|
|
|
|
|
|
|
|
|
def get_values(sensorId, min_ts, max_ts, limit):
|
|
|
|
ret = {}
|
|
|
|
if sensorId:
|
|
|
|
try:
|
2020-02-10 16:05:18 +01:00
|
|
|
url = f"{URL_BASE}/sensor/get_values/{sensorId}?min_ts={min_ts}&max_ts={max_ts}&limit={limit}"
|
2020-02-10 15:46:41 +01:00
|
|
|
# print(url)
|
2019-11-14 00:50:53 +01:00
|
|
|
res = requests.get(url)
|
|
|
|
ret = res.json()[sensorId]
|
|
|
|
except Exception as ex:
|
2020-02-10 16:05:18 +01:00
|
|
|
print(f"Exception Type: {type(ex).__name__}, args:\n{ex.args}")
|
2019-11-14 00:50:53 +01:00
|
|
|
return ret
|
|
|
|
|
2020-02-10 16:05:18 +01:00
|
|
|
def pTime(value, fmt="%Y/%m/%d %H:%M"):
|
|
|
|
if value > 0:
|
|
|
|
return time.strftime(fmt, time.localtime(float(value)))
|
|
|
|
else:
|
|
|
|
return 0
|
|
|
|
|
2019-11-03 16:38:01 +01:00
|
|
|
|
2019-11-14 00:50:53 +01:00
|
|
|
sensors = get_sensors()
|
|
|
|
sensor = next(iter(sensors), None)
|
2019-11-14 21:39:04 +01:00
|
|
|
tabs = []
|
|
|
|
for s in sensors:
|
|
|
|
sensorType = sensors[s]["sensorType"]
|
|
|
|
tabs.append(dcc.Tab(label=sensorType, value=s))
|
2019-11-14 00:50:53 +01:00
|
|
|
|
|
|
|
external_stylesheets = [dbc.themes.BOOTSTRAP]
|
2019-11-11 10:25:32 +01:00
|
|
|
meta_tags=[{"name": "viewport", "content": "width=device-width, initial-scale=1"}]
|
2019-11-03 16:38:01 +01:00
|
|
|
|
2019-11-11 10:25:32 +01:00
|
|
|
app = dash.Dash(__name__, external_stylesheets=external_stylesheets, meta_tags=meta_tags)
|
2019-11-14 00:50:53 +01:00
|
|
|
app.title = "dashboard.ykonni.de"
|
2019-11-03 16:38:01 +01:00
|
|
|
|
|
|
|
|
|
|
|
app.layout = html.Div(children=[
|
2019-11-11 10:25:32 +01:00
|
|
|
html.H1(children='dashboard.ykonni.de'),
|
2019-11-14 21:39:04 +01:00
|
|
|
dbc.Row([
|
|
|
|
dbc.Col(dcc.Tabs(id="tabs-select-sensor", value=sensor, children=tabs))
|
|
|
|
]),
|
2019-11-14 00:50:53 +01:00
|
|
|
dbc.Row([
|
|
|
|
dbc.Col(
|
|
|
|
dcc.Graph(
|
|
|
|
id='graph-sensor-values',
|
|
|
|
figure={
|
2019-11-15 11:52:48 +01:00
|
|
|
'data': [ {'x': [0], 'y': [0], 'mode': 'line', 'name': 'None'} ],
|
2019-11-14 21:39:04 +01:00
|
|
|
'layout': { 'title': 'initial values' }
|
2019-11-14 00:50:53 +01:00
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
]),
|
|
|
|
dbc.Row([
|
|
|
|
dbc.Col([
|
2019-11-14 21:39:04 +01:00
|
|
|
html.Div(id='slider-min-txt', style={'marginLeft': '5em', 'marginRight': '3em'}),
|
|
|
|
html.Div([
|
|
|
|
dcc.Slider(id='slider-min', min=0, max=round(time.time()), step=600,
|
|
|
|
value=0 ),
|
|
|
|
], style={'marginLeft': '5em', 'marginRight': '3em'}
|
2019-11-14 00:50:53 +01:00
|
|
|
),
|
|
|
|
]),
|
|
|
|
dbc.Col([
|
2019-11-14 21:39:04 +01:00
|
|
|
html.Div(id='slider-max-txt', style={'marginLeft': '3em', 'marginRight':
|
|
|
|
'3em'}),
|
|
|
|
html.Div([
|
|
|
|
dcc.Slider(id='slider-max', min=0, max=round(time.time()), step=600,
|
|
|
|
value=round(time.time())),
|
|
|
|
], style={'marginLeft': '3em', 'marginRight': '3em'}
|
2019-11-14 00:50:53 +01:00
|
|
|
),
|
|
|
|
]),
|
|
|
|
dbc.Col([
|
2019-11-14 21:39:04 +01:00
|
|
|
html.Div(id='slider-limit-txt', style={'marginLeft': '3em', 'marginRight': '5em'}),
|
|
|
|
html.Div([
|
|
|
|
dcc.Slider(id='slider-limit', min=0, max=1000, step=10, value=0 ),
|
|
|
|
], style={'marginLeft': '3em', 'marginRight': '5em'}
|
2019-11-14 00:50:53 +01:00
|
|
|
),
|
|
|
|
]),
|
|
|
|
]),
|
2019-11-03 16:38:01 +01:00
|
|
|
])
|
|
|
|
|
2019-11-14 00:50:53 +01:00
|
|
|
@app.callback(
|
|
|
|
[Output('slider-min', 'min'), Output('slider-min', 'value'),
|
2020-02-10 15:46:41 +01:00
|
|
|
Output('slider-min', 'max')],
|
2019-11-14 21:39:04 +01:00
|
|
|
[Input('tabs-select-sensor', 'value')])
|
2019-11-14 00:50:53 +01:00
|
|
|
def update_slider_min(sensorId):
|
|
|
|
res = get_values(sensorId, 0, int(time.time()), 1)
|
|
|
|
min_ts = 0
|
2020-02-10 15:46:41 +01:00
|
|
|
# default last 7 days
|
|
|
|
cur_ts = round(time.time() - (60*60*24*7))
|
|
|
|
max_ts = int(time.time())
|
2019-11-14 00:50:53 +01:00
|
|
|
sensorType = None
|
|
|
|
if "values" in res:
|
|
|
|
min_ts = int(res["values"][0]["ts"])
|
|
|
|
sensorType = res["sensorType"]
|
|
|
|
|
2020-02-10 16:05:18 +01:00
|
|
|
# print(f"min: [{min_ts} [{cur_ts}] {max_ts}]"
|
2020-02-10 15:46:41 +01:00
|
|
|
return min_ts, cur_ts, max_ts
|
2019-11-03 16:38:01 +01:00
|
|
|
|
|
|
|
|
|
|
|
@app.callback(
|
2019-11-15 11:52:48 +01:00
|
|
|
Output('slider-min-txt', 'children'),
|
2019-11-14 00:50:53 +01:00
|
|
|
[Input('slider-min', 'value')])
|
2020-02-10 15:46:41 +01:00
|
|
|
def update_slider_min_txt(value):
|
2020-02-10 16:05:18 +01:00
|
|
|
return f"From: {pTime(value)}"
|
2019-11-14 00:50:53 +01:00
|
|
|
|
2020-02-10 15:46:41 +01:00
|
|
|
@app.callback(
|
|
|
|
[Output('slider-max', 'min'), Output('slider-max', 'value'),
|
|
|
|
Output('slider-max', 'max')],
|
|
|
|
[Input('tabs-select-sensor', 'value')])
|
|
|
|
def update_slider_max(sensorId):
|
|
|
|
res = get_values(sensorId, 0, int(time.time()), 1)
|
|
|
|
min_ts = 0
|
|
|
|
max_ts = int(time.time())
|
|
|
|
sensorType = None
|
|
|
|
if "values" in res:
|
|
|
|
min_ts = int(res["values"][0]["ts"])
|
|
|
|
sensorType = res["sensorType"]
|
|
|
|
|
2020-02-10 16:05:18 +01:00
|
|
|
# print(f"max: [{min_ts} [{max_ts}] {max_ts}]"
|
2020-02-10 15:46:41 +01:00
|
|
|
return min_ts, max_ts, max_ts
|
|
|
|
|
2019-11-14 00:50:53 +01:00
|
|
|
|
|
|
|
@app.callback(
|
2019-11-15 11:52:48 +01:00
|
|
|
Output('slider-max-txt', 'children'),
|
2019-11-14 00:50:53 +01:00
|
|
|
[Input('slider-max', 'value')])
|
2020-02-10 15:46:41 +01:00
|
|
|
def update_slider_max_txt(value):
|
2020-02-10 16:05:18 +01:00
|
|
|
return f"To: {pTime(value)}"
|
2019-11-14 00:50:53 +01:00
|
|
|
|
|
|
|
|
|
|
|
@app.callback(
|
2020-02-10 15:46:41 +01:00
|
|
|
Output('slider-limit-txt', 'children'),
|
|
|
|
[Input('slider-limit', 'value')])
|
|
|
|
def update_slider_limit_txt(value):
|
2020-02-10 16:05:18 +01:00
|
|
|
return f"Limit: {value if value > 0 else None}"
|
2020-02-10 15:46:41 +01:00
|
|
|
|
|
|
|
|
|
|
|
@app.callback(
|
|
|
|
Output('graph-sensor-values', 'figure'),
|
2019-11-14 21:39:04 +01:00
|
|
|
[Input('tabs-select-sensor', 'value'), Input('slider-min', 'value'),
|
2019-11-14 00:50:53 +01:00
|
|
|
Input('slider-max', 'value'), Input('slider-limit', 'value')])
|
|
|
|
def update_graph_sensor_values(sensorId, min_ts, max_ts, limit):
|
2020-02-10 15:46:41 +01:00
|
|
|
res = {}
|
|
|
|
if min_ts > 0:
|
|
|
|
res = get_values(sensorId, min_ts, max_ts, limit)
|
2019-11-14 00:50:53 +01:00
|
|
|
if "values" in res:
|
|
|
|
v = res["values"]
|
|
|
|
s = res["sensorType"]
|
2020-02-10 16:05:18 +01:00
|
|
|
x = [pTime(v[i]["ts"], fmt="%m%d-%H%M") for i in range(len(v))]
|
2020-02-10 15:46:41 +01:00
|
|
|
if s == "luminance":
|
|
|
|
y = [log10(v[i]["value"]/5+1) for i in range(len(v))]
|
|
|
|
else:
|
|
|
|
y = [v[i]["value"] for i in range(len(v))]
|
2019-11-10 20:59:08 +01:00
|
|
|
else:
|
2019-11-14 00:50:53 +01:00
|
|
|
s = sensorId
|
|
|
|
x = [0]
|
|
|
|
y = [0]
|
2019-11-03 16:38:01 +01:00
|
|
|
return {
|
2020-02-10 16:05:18 +01:00
|
|
|
'data': [ {'x': x, 'y': y, 'mode': 'line', 'name': f'{s}'} ],
|
|
|
|
'layout': { 'title': f'Data for sensor: {s} ({len(x)} elements)' }
|
2020-02-10 15:46:41 +01:00
|
|
|
}
|
2019-11-03 16:38:01 +01:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
2019-11-11 10:25:32 +01:00
|
|
|
app.run_server(port=8081,debug=True)
|