homecontrol-dash: select range, limits, arrange in columns, cleanup

This commit is contained in:
Konstantin Koslowski 2019-11-14 00:50:53 +01:00
parent 4b7f2662b8
commit 09412adcfb
2 changed files with 132 additions and 45 deletions

View file

@ -8,6 +8,7 @@ verify_ssl = true
[packages] [packages]
dash = "*" dash = "*"
dash-daq = "*" dash-daq = "*"
dash-bootstrap-components = "*"
requests = "*" requests = "*"
[requires] [requires]

View file

@ -1,22 +1,49 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import dash import dash
import dash_bootstrap_components as dbc
import dash_core_components as dcc import dash_core_components as dcc
import dash_html_components as html import dash_html_components as html
from dash.dependencies import Input, Output from dash.dependencies import Input, Output
import time import time
import requests import requests
from math import inf
URL_BASE="http://innocence:5000" URL_BASE="http://innocence:5000"
x = [1] def get_sensors():
y = [2] ret = {}
try:
url = "%s/sensor/get" % URL_BASE
res = requests.get(url)
ret = res.json()
except Exception as ex:
print('Exception Type:%s, args:\n%s' % (type(ex).__name__, ex.args))
return ret
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
def get_values(sensorId, min_ts, max_ts, limit):
ret = {}
if sensorId:
try:
url = "%s/sensor/get_values/%s?min_ts=%s&max_ts=%s&limit=%s" % (URL_BASE,
sensorId, min_ts, max_ts, limit)
res = requests.get(url)
ret = res.json()[sensorId]
except Exception as ex:
print('Exception Type:%s, args:\n%s' % (type(ex).__name__, ex.args))
return ret
sensors = get_sensors()
sensor = next(iter(sensors), None)
# external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
external_stylesheets = [dbc.themes.BOOTSTRAP]
meta_tags=[{"name": "viewport", "content": "width=device-width, initial-scale=1"}] meta_tags=[{"name": "viewport", "content": "width=device-width, initial-scale=1"}]
app = dash.Dash(__name__, external_stylesheets=external_stylesheets, meta_tags=meta_tags) app = dash.Dash(__name__, external_stylesheets=external_stylesheets, meta_tags=meta_tags)
app.title = "dashboard.ykonni.de"
available_sensors = ["undefined"]
app.layout = html.Div(children=[ app.layout = html.Div(children=[
html.H1(children='dashboard.ykonni.de'), html.H1(children='dashboard.ykonni.de'),
@ -24,62 +51,121 @@ app.layout = html.Div(children=[
html.Div(children=''' html.Div(children='''
visualize sensor data visualize sensor data
'''), '''),
dbc.Row([
dbc.Col(
dcc.Graph( dcc.Graph(
id='example-graph', id='graph-sensor-values',
figure={ figure={
'data': [ 'data': [
{'x': x, 'y': y, 'mode': 'markers', 'name': 'SF'} {'x': [0], 'y': [0], 'mode': 'markers', 'name': 'None'}
], ],
'layout': { 'layout': {
'title': 'initial values' 'title': 'initial values'
} }
} }
), )
)
]),
dbc.Row([
dbc.Col([
html.Div(id='select-sensor-txt'),
dcc.Dropdown( dcc.Dropdown(
id='select-sensor', id='select-sensorid',
options=[{'label': i, 'value': i} for i in available_sensors], options=[{'label': sensors[i]["sensorType"], 'value': i} for i in sensors],
value="undefined" value=sensor),
]),
dbc.Col([
html.Div(id='slider-min-txt'),
dcc.Slider(
id='slider-min',
min=0,
max=round(time.time()),
step=600,
value=0
), ),
html.Button(id='refresh-button', n_clicks=0, children='refresh') ]),
dbc.Col([
html.Div(id='slider-max-txt'),
dcc.Slider(
id='slider-max',
min=0,
max=round(time.time()),
step=600,
value=round(time.time())
),
]),
dbc.Col([
html.Div(id='slider-limit-txt'),
dcc.Slider(
id='slider-limit',
min=0,
max=1000,
step=10,
value=0,
),
]),
]),
]) ])
@app.callback(
[Output('slider-min', 'min'), Output('slider-min', 'value'),
Output('slider-max', 'min'), Output('select-sensor-txt', 'children')],
[Input('select-sensorid', 'value')])
def update_slider_min(sensorId):
res = get_values(sensorId, 0, int(time.time()), 1)
min_ts = 0
sensorType = None
if "values" in res:
min_ts = int(res["values"][0]["ts"])
sensorType = res["sensorType"]
return min_ts, min_ts, min_ts, "Sensor: %s" % sensorType
@app.callback( @app.callback(
Output('select-sensor', 'options'), Output('slider-limit-txt', 'children'),
[Input('refresh-button', 'n_clicks')]) [Input('slider-limit', 'value')])
def update_list(n_clicks): def update_slider_limit(value):
url = "%s/sensor/get" % URL_BASE return "Limit: %s" % (value if value > 0 else None)
print(url)
res = requests.get(url)
content = res.json()
options = [{'label': content[i]["sensorType"], 'value': i} for i in content]
return options
@app.callback( @app.callback(
Output('example-graph', 'figure'), Output('slider-min-txt', 'children'),
[Input('refresh-button', 'n_clicks'), Input('select-sensor', 'value')]) [Input('slider-min', 'value')])
def update_graph(n_clicks, sensorId): def update_slider_min(value):
if not sensorId == "undefined": return "From: %s" % (time.strftime("%Y/%m/%d %H:%M", time.localtime(float(value))) if
# url = "%s/sensor/get_values/%s?limit=10" % (URL_BASE, sensorId) value > 0 else 0)
url = "%s/sensor/get_values/%s" % (URL_BASE, sensorId)
res = requests.get(url)
content = res.json() @app.callback(
v = content[sensorId]["values"] Output('slider-max-txt', 'children'),
sensorType = content[sensorId]["sensorType"] [Input('slider-max', 'value')])
def update_slider_max(value):
return "To: %s" % (time.strftime("%Y/%m/%d %H:%M", time.localtime(float(value))))
@app.callback(
Output('graph-sensor-values', 'figure'),
[Input('select-sensorid', 'value'), Input('slider-min', 'value'),
Input('slider-max', 'value'), Input('slider-limit', 'value')])
def update_graph_sensor_values(sensorId, min_ts, max_ts, limit):
res = get_values(sensorId, min_ts, max_ts, limit)
if "values" in res:
v = res["values"]
s = res["sensorType"]
l = len(v)
x = [time.strftime("%m%d-%H%M", time.localtime(float(v[i]["ts"]))) for i in range(len(v))] x = [time.strftime("%m%d-%H%M", time.localtime(float(v[i]["ts"]))) for i in range(len(v))]
y = [v[i]["value"] for i in range(len(v))] y = [v[i]["value"] for i in range(len(v))]
else: else:
sensorType = sensorId s = sensorId
x = [1] x = [0]
y = [1] y = [0]
return { return {
'data': [ 'data': [
{'x': x, 'y': y, 'mode': 'markers', 'name': "%s" % (sensorType)} {'x': x, 'y': y, 'mode': 'markers', 'name': "%s" % (s)}
], ],
'layout': { 'layout': {
'title': 'Data for sensor: %s' % (sensorType) 'title': 'Data for sensor: %s (%d elements)' % (s, l)
} }
} }