homecontrol-dash: select range, limits, arrange in columns, cleanup
This commit is contained in:
		
							parent
							
								
									4b7f2662b8
								
							
						
					
					
						commit
						09412adcfb
					
				
					 2 changed files with 132 additions and 45 deletions
				
			
		
							
								
								
									
										1
									
								
								Pipfile
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								Pipfile
									
										
									
									
									
								
							|  | @ -8,6 +8,7 @@ verify_ssl = true | |||
| [packages] | ||||
| dash = "*" | ||||
| dash-daq = "*" | ||||
| dash-bootstrap-components = "*" | ||||
| requests = "*" | ||||
| 
 | ||||
| [requires] | ||||
|  |  | |||
|  | @ -1,22 +1,49 @@ | |||
| #!/usr/bin/env python3 | ||||
| import dash | ||||
| import dash_bootstrap_components as dbc | ||||
| import dash_core_components as dcc | ||||
| import dash_html_components as html | ||||
| from dash.dependencies import Input, Output | ||||
| import time | ||||
| import requests | ||||
| from math import inf | ||||
| 
 | ||||
| URL_BASE="http://innocence:5000" | ||||
| 
 | ||||
| x = [1] | ||||
| y = [2] | ||||
| def get_sensors(): | ||||
|     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"}] | ||||
| 
 | ||||
| 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=[ | ||||
|     html.H1(children='dashboard.ykonni.de'), | ||||
|  | @ -24,62 +51,121 @@ app.layout = html.Div(children=[ | |||
|     html.Div(children=''' | ||||
|         visualize sensor data | ||||
|     '''), | ||||
|     dcc.Graph( | ||||
|         id='example-graph', | ||||
|         figure={ | ||||
|             'data': [ | ||||
|                 {'x': x, 'y': y, 'mode': 'markers', 'name': 'SF'} | ||||
|             ], | ||||
|             'layout': { | ||||
|                 'title': 'initial values' | ||||
|             } | ||||
|         } | ||||
|     ), | ||||
|     dcc.Dropdown( | ||||
|         id='select-sensor', | ||||
|         options=[{'label': i, 'value': i} for i in available_sensors], | ||||
|         value="undefined" | ||||
|     ), | ||||
|     html.Button(id='refresh-button', n_clicks=0, children='refresh') | ||||
|     dbc.Row([ | ||||
|         dbc.Col( | ||||
|             dcc.Graph( | ||||
|                 id='graph-sensor-values', | ||||
|                 figure={ | ||||
|                     'data': [ | ||||
|                         {'x': [0], 'y': [0], 'mode': 'markers', 'name': 'None'} | ||||
|                     ], | ||||
|                     'layout': { | ||||
|                         'title': 'initial values' | ||||
|                     } | ||||
|                 } | ||||
|             ) | ||||
|         ) | ||||
|     ]), | ||||
|     dbc.Row([ | ||||
|         dbc.Col([ | ||||
|             html.Div(id='select-sensor-txt'), | ||||
|             dcc.Dropdown( | ||||
|                 id='select-sensorid', | ||||
|                 options=[{'label': sensors[i]["sensorType"], 'value': i} for i in sensors], | ||||
|                 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 | ||||
|             ), | ||||
|         ]), | ||||
|         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( | ||||
|     Output('select-sensor', 'options'), | ||||
|     [Input('refresh-button', 'n_clicks')]) | ||||
| def update_list(n_clicks): | ||||
|     url = "%s/sensor/get" % URL_BASE | ||||
|     print(url) | ||||
|     res = requests.get(url) | ||||
|     content = res.json() | ||||
|     options = [{'label': content[i]["sensorType"], 'value': i} for i in content] | ||||
|     return options | ||||
|         Output('slider-limit-txt', 'children'), | ||||
|         [Input('slider-limit', 'value')]) | ||||
| def update_slider_limit(value): | ||||
|     return "Limit: %s" % (value if value > 0 else None) | ||||
| 
 | ||||
| 
 | ||||
| @app.callback( | ||||
|     Output('example-graph', 'figure'), | ||||
|     [Input('refresh-button', 'n_clicks'), Input('select-sensor', 'value')]) | ||||
| def update_graph(n_clicks, sensorId): | ||||
|     if not sensorId == "undefined": | ||||
|         # url = "%s/sensor/get_values/%s?limit=10" % (URL_BASE, sensorId) | ||||
|         url = "%s/sensor/get_values/%s" % (URL_BASE, sensorId) | ||||
|         res = requests.get(url) | ||||
|         content = res.json() | ||||
|         v = content[sensorId]["values"] | ||||
|         sensorType = content[sensorId]["sensorType"] | ||||
|         Output('slider-min-txt', 'children'), | ||||
|         [Input('slider-min', 'value')]) | ||||
| def update_slider_min(value): | ||||
|     return "From: %s" % (time.strftime("%Y/%m/%d %H:%M", time.localtime(float(value))) if | ||||
|             value > 0 else 0) | ||||
| 
 | ||||
| 
 | ||||
| @app.callback( | ||||
|         Output('slider-max-txt', 'children'), | ||||
|         [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))] | ||||
|         y = [v[i]["value"] for i in range(len(v))] | ||||
|     else: | ||||
|         sensorType = sensorId | ||||
|         x = [1] | ||||
|         y = [1] | ||||
|         s = sensorId | ||||
|         x = [0] | ||||
|         y = [0] | ||||
| 
 | ||||
|     return { | ||||
|         'data': [ | ||||
|             {'x': x, 'y': y, 'mode': 'markers', 'name': "%s" % (sensorType)} | ||||
|             {'x': x, 'y': y, 'mode': 'markers', 'name': "%s" % (s)} | ||||
|         ], | ||||
|         'layout': { | ||||
|             'title': 'Data for sensor: %s' % (sensorType) | ||||
|             'title': 'Data for sensor: %s (%d elements)' % (s, l) | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue