homecontrol-dash: fix/merge callbacks
This commit is contained in:
		
							parent
							
								
									27a70361fb
								
							
						
					
					
						commit
						b84d2ce1fb
					
				
					 1 changed files with 160 additions and 67 deletions
				
			
		|  | @ -109,7 +109,7 @@ class HCDash: | ||||||
|         self.logger.debug(f"set_level: {req}") |         self.logger.debug(f"set_level: {req}") | ||||||
|         requests.post(f"{self.config.get('address')}/actor/command", json=req) |         requests.post(f"{self.config.get('address')}/actor/command", json=req) | ||||||
| 
 | 
 | ||||||
|     def get_values(self, sensorId, min_ts, max_ts, limit): |     def get_sensor_values(self, sensorId, min_ts, max_ts, limit): | ||||||
|         ret = {} |         ret = {} | ||||||
|         if sensorId: |         if sensorId: | ||||||
|             try: |             try: | ||||||
|  | @ -120,6 +120,18 @@ class HCDash: | ||||||
|                 self.logger.error(f"Exception Type: {type(ex).__name__}, args:\n{ex.args}") |                 self.logger.error(f"Exception Type: {type(ex).__name__}, args:\n{ex.args}") | ||||||
|         return ret |         return ret | ||||||
| 
 | 
 | ||||||
|  |     def get_actor_levels(self, actorId, min_ts, max_ts, limit): | ||||||
|  |         self.logger.debug(f"get_actor_levels: {actorId}") | ||||||
|  |         ret = {} | ||||||
|  |         if actorId: | ||||||
|  |             try: | ||||||
|  |                 url = f"{self.config.get('address')}/actor/get_levels/{actorId}?min_ts={min_ts}&max_ts={max_ts}&limit={limit}" | ||||||
|  |                 res = requests.get(url) | ||||||
|  |                 ret = res.json()[actorId] | ||||||
|  |             except Exception as ex: | ||||||
|  |                 self.logger.error(f"Exception Type: {type(ex).__name__}, args:\n{ex.args}") | ||||||
|  |         return ret | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|     def pTime(self, value, fmt="%Y/%m/%d %H:%M"): |     def pTime(self, value, fmt="%Y/%m/%d %H:%M"): | ||||||
|         if value > 0: |         if value > 0: | ||||||
|  | @ -181,9 +193,7 @@ class HCDash: | ||||||
|                         dbc.Col(dcc.Tabs(id="tabs-select-actor", value=actor, |                         dbc.Col(dcc.Tabs(id="tabs-select-actor", value=actor, | ||||||
|                             children=actor_tabs)) |                             children=actor_tabs)) | ||||||
|                     ]), |                     ]), | ||||||
|                     dbc.Row([ |  | ||||||
|                     html.Div(id="actor-data"), |                     html.Div(id="actor-data"), | ||||||
|                     ]), |  | ||||||
|                 ]) |                 ]) | ||||||
|             else: |             else: | ||||||
|                 return html.Div([ |                 return html.Div([ | ||||||
|  | @ -191,12 +201,15 @@ class HCDash: | ||||||
|                     ]), None, None |                     ]), None, None | ||||||
| 
 | 
 | ||||||
|         @app.callback( |         @app.callback( | ||||||
|                 Output("sensor-data", "children"), |                 [Output("sensor-data", "children"), | ||||||
|  |                     Output('slider-min', 'min'), Output('slider-min', 'value'), | ||||||
|  |                     Output('slider-min', 'max'), Output('slider-max', 'min'), | ||||||
|  |                     Output('slider-max', 'value'), Output('slider-max', 'max')], | ||||||
|                 [Input("tabs-select-sensor", "value")]) |                 [Input("tabs-select-sensor", "value")]) | ||||||
|         def update_sensor(value): |         def update_sensor(sensorId): | ||||||
|             self.logger.debug(f"update_sensor: {value}") |             self.logger.debug(f"update_sensor: {sensorId}") | ||||||
|             if value: |             if sensorId: | ||||||
|                 return [ |                 sensor_data = [ | ||||||
|                     dbc.Row([ |                     dbc.Row([ | ||||||
|                         dbc.Col( |                         dbc.Col( | ||||||
|                             dcc.Graph( |                             dcc.Graph( | ||||||
|  | @ -235,40 +248,16 @@ class HCDash: | ||||||
|                         ]) |                         ]) | ||||||
|                     ]), |                     ]), | ||||||
|                 ] |                 ] | ||||||
| 
 |                 res = self.get_sensor_values(sensorId, 0, int(time.time()), 1) | ||||||
|         @app.callback( |  | ||||||
|                 Output("actor-data", "children"), |  | ||||||
|                 [Input("tabs-select-actor", "value")]) |  | ||||||
|         def update_actor(value): |  | ||||||
|             self.logger.debug(f"update_actor: {value}") |  | ||||||
|             if value: |  | ||||||
|                 return [ |  | ||||||
|                         daq.ColorPicker( |  | ||||||
|                             id="color-picker", |  | ||||||
|                             label="Color Picker", |  | ||||||
|                             size=360, |  | ||||||
|                             value=dict(hex="#268bd2") |  | ||||||
|                             ), |  | ||||||
|                         html.P(id="empty") |  | ||||||
|                     ] |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         ## sensor callbacks |  | ||||||
|         @app.callback( |  | ||||||
|                 [Output('slider-min', 'min'), Output('slider-min', 'value'), |  | ||||||
|                     Output('slider-min', 'max')], |  | ||||||
|                 [Input('tabs-select-sensor', 'value')]) |  | ||||||
|         def update_slider_min(sensorId): |  | ||||||
|             res = self.get_values(sensorId, 0, int(time.time()), 1) |  | ||||||
|                 min_ts = 0 |                 min_ts = 0 | ||||||
|                 # default last 7 days |                 # default last 7 days | ||||||
|                 cur_ts = round(time.time() - (60*60*24*7)) |                 cur_ts = round(time.time() - (60*60*24*7)) | ||||||
|                 max_ts = int(time.time()) |                 max_ts = int(time.time()) | ||||||
|             sensorType = None |  | ||||||
|                 if "values" in res: |                 if "values" in res: | ||||||
|                     min_ts = int(res["values"][0]["ts"]) |                     min_ts = int(res["values"][0]["ts"]) | ||||||
|                 sensorType = res["sensorType"] |                 # sensor_data, min: [min, cur, max], max: [min, max, max] | ||||||
|             return min_ts, cur_ts, max_ts |                 return sensor_data, min_ts, cur_ts, max_ts, min_ts, max_ts, max_ts | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|         @app.callback( |         @app.callback( | ||||||
|                 Output('slider-min-txt', 'children'), |                 Output('slider-min-txt', 'children'), | ||||||
|  | @ -277,21 +266,6 @@ class HCDash: | ||||||
|             return f"From: {self.pTime(value)}" |             return f"From: {self.pTime(value)}" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|         @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 = self.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"] |  | ||||||
|             return min_ts, max_ts, max_ts |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         @app.callback( |         @app.callback( | ||||||
|                 Output('slider-max-txt', 'children'), |                 Output('slider-max-txt', 'children'), | ||||||
|                 [Input('slider-max', 'value')]) |                 [Input('slider-max', 'value')]) | ||||||
|  | @ -313,7 +287,7 @@ class HCDash: | ||||||
|         def update_graph_sensor_values(sensorId, min_ts, max_ts, limit): |         def update_graph_sensor_values(sensorId, min_ts, max_ts, limit): | ||||||
|             res = {} |             res = {} | ||||||
|             if min_ts > 0: |             if min_ts > 0: | ||||||
|                 res = self.get_values(sensorId, min_ts, max_ts, limit) |                 res = self.get_sensor_values(sensorId, min_ts, max_ts, limit) | ||||||
|             if "values" in res: |             if "values" in res: | ||||||
|                 v = res["values"] |                 v = res["values"] | ||||||
|                 s = res["sensorType"] |                 s = res["sensorType"] | ||||||
|  | @ -333,16 +307,135 @@ class HCDash: | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|         ## actor callbacks |         ## actor callbacks | ||||||
|  |         @app.callback( | ||||||
|  |             [Output("actor-data", "children"), | ||||||
|  |                 Output("slider-actor-min", "min"), Output("slider-actor-min", "value"), | ||||||
|  |                 Output("slider-actor-min", "max"), Output("slider-actor-max", "min"), | ||||||
|  |                 Output("slider-actor-max", "value"), Output("slider-actor-max", "max")], | ||||||
|  |             [Input("tabs-select-actor", "value")]) | ||||||
|  |         def update_actor(actorId): | ||||||
|  |             self.logger.debug(f"update_actor: {actorId}") | ||||||
|  |             if actorId: | ||||||
|  |                 res = self.get_actors() | ||||||
|  |                 l = res[actorId].get("level") or 0 | ||||||
|  |                 level = f"#{format(l, '06x')}" | ||||||
|  |                 actor_data = [ | ||||||
|  |                     dbc.Row([ | ||||||
|  |                         dbc.Col( | ||||||
|  |                             dcc.Graph( | ||||||
|  |                                 id='graph-actor-values', | ||||||
|  |                                 figure={ | ||||||
|  |                                     'data': [ {'x': [0], 'y': [0], 'mode': 'line', 'name': 'None'} ], | ||||||
|  |                                     'layout': { 'title': 'initial values' } | ||||||
|  |                                 } | ||||||
|  |                             ) | ||||||
|  |                         ) | ||||||
|  |                     ]), | ||||||
|  |                     dbc.Row([ | ||||||
|  |                         dbc.Col([ | ||||||
|  |                             html.Div(id='slider-actor-min-txt', style={'marginLeft': '5em', 'marginRight': '3em'}), | ||||||
|  |                             html.Div([ | ||||||
|  |                                 dcc.Slider(id='slider-actor-min', min=0, max=round(time.time()), step=600, | ||||||
|  |                                     value=0 ), | ||||||
|  |                                 ], style={'marginLeft': '5em', 'marginRight': '3em'} | ||||||
|  |                             ), | ||||||
|  |                         ]), | ||||||
|  |                         dbc.Col([ | ||||||
|  |                             html.Div(id='slider-actor-max-txt', style={'marginLeft': '3em', 'marginRight': | ||||||
|  |                                 '3em'}), | ||||||
|  |                             html.Div([ | ||||||
|  |                                 dcc.Slider(id='slider-actor-max', min=0, max=round(time.time()), step=600, | ||||||
|  |                                     value=round(time.time())), | ||||||
|  |                                 ], style={'marginLeft': '3em', 'marginRight': '3em'} | ||||||
|  |                             ), | ||||||
|  |                         ]), | ||||||
|  |                         dbc.Col([ | ||||||
|  |                             html.Div(id='slider-actor-limit-txt', style={'marginLeft': '3em', 'marginRight': '5em'}), | ||||||
|  |                             html.Div([ | ||||||
|  |                                 dcc.Slider(id='slider-actor-limit', min=0, max=1000, step=10, value=0 ), | ||||||
|  |                                 ], style={'marginLeft': '3em', 'marginRight': '5em'} | ||||||
|  |                             ), | ||||||
|  |                         ]) | ||||||
|  |                     ]), | ||||||
|  |                     dbc.Row([ | ||||||
|  |                         daq.ColorPicker( | ||||||
|  |                             id="color-picker", | ||||||
|  |                             label="Color Picker", | ||||||
|  |                             size=360, | ||||||
|  |                             value=dict(hex=level) | ||||||
|  |                             ), | ||||||
|  |                         html.P(id="empty") | ||||||
|  |                     ]), | ||||||
|  |                 ] | ||||||
|  |                 res = self.get_actor_levels(actorId, 0, int(time.time()), 1) | ||||||
|  |                 min_ts = 0 | ||||||
|  |                 # default last 7 days | ||||||
|  |                 cur_ts = round(time.time() - (60*60*24*7)) | ||||||
|  |                 max_ts = int(time.time()) | ||||||
|  |                 if "levels" in res: | ||||||
|  |                     min_ts = int(res["levels"][0]["ts"]) | ||||||
|  |                 # actor_data, min: [min, cur, max], max: [min, max, max] | ||||||
|  |                 return actor_data, min_ts, cur_ts, max_ts, min_ts, max_ts, max_ts | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         @app.callback( | ||||||
|  |                 Output('slider-actor-min-txt', 'children'), | ||||||
|  |                 [Input('slider-actor-min', 'value')]) | ||||||
|  |         def update_slider_actor_min_txt(value): | ||||||
|  |             # self.logger.debug(f"update_slider_actor_min_txt: {value}") | ||||||
|  |             return f"From: {self.pTime(value)}" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         @app.callback( | ||||||
|  |                 Output('slider-actor-max-txt', 'children'), | ||||||
|  |                 [Input('slider-actor-max', 'value')]) | ||||||
|  |         def update_slider_actor_max_txt(value): | ||||||
|  |             # self.logger.debug(f"update_slider_actor_max_txt: {value}") | ||||||
|  |             return f"To: {self.pTime(value)}" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         @app.callback( | ||||||
|  |                 Output('slider-actor-limit-txt', 'children'), | ||||||
|  |                 [Input('slider-actor-limit', 'value')]) | ||||||
|  |         def update_slider_actor_limit_txt(value): | ||||||
|  |             return f"Limit: {value if value > 0 else None}" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|         @app.callback( |         @app.callback( | ||||||
|             Output("empty", "value"), |             Output("empty", "value"), | ||||||
|             [Input('tabs-select-actor', 'value'), Input('color-picker', 'value')]) |             [Input("tabs-select-actor", "value"), Input("color-picker", "value")]) | ||||||
|         def set_level(actorId, level): |         def set_level(actorId, level): | ||||||
|             l = f"0x{level.get('hex').replace('#', '')}" |             l = f"0x{level.get('hex').replace('#', '')}" | ||||||
|             if l: |             if l: | ||||||
|                 self.set_level(actorId, l) |                 self.set_level(actorId, l) | ||||||
|                 self.logger.debug(f"hex: {l}") |  | ||||||
|             return "" |             return "" | ||||||
| 
 | 
 | ||||||
|  |         @app.callback( | ||||||
|  |             Output('graph-actor-values', 'figure'), | ||||||
|  |             [Input('tabs-select-actor', 'value'), Input('slider-actor-min', 'value'), | ||||||
|  |                 Input('slider-actor-max', 'value'), Input('slider-actor-limit', 'value')]) | ||||||
|  |         def update_graph_actor(actorId, min_ts, max_ts, limit): | ||||||
|  |             self.logger.debug(f"update_graph_actor: {actorId}, {min_ts}, {max_ts}, {limit}") | ||||||
|  |             res = {} | ||||||
|  |             if min_ts > 0: | ||||||
|  |                 res = self.get_actor_levels(actorId, min_ts, max_ts, limit) | ||||||
|  |             if "levels" in res: | ||||||
|  |                 v = res["levels"] | ||||||
|  |                 s = res["actorType"] | ||||||
|  |                 x = [self.pTime(v[i]["ts"], fmt="%m%d-%H%M") for i in range(len(v))] | ||||||
|  |                 y = [v[i]["value"] for i in range(len(v))] | ||||||
|  |                 # y = [[(int(v[i]["value"]) >> 16) & 0xff, (int(v[i]["value"]) >> 8) & 0xff, | ||||||
|  |                 #     int(v[i]["value"]) & 0xff] for i in range(len(v))] | ||||||
|  |             else: | ||||||
|  |                 s = actorId | ||||||
|  |                 x = [0] | ||||||
|  |                 y = [0] | ||||||
|  |             return { | ||||||
|  |                 'data': [ {'x': x, 'y': y, 'mode': 'markers', 'name': f'{s}'} ], | ||||||
|  |                 'layout': { 'title': f'Data for sensor: {s} ({len(x)} elements)' } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|         app.run_server(host="0.0.0.0", port=self.config.get("port"), debug=self.config.get("debug")) |         app.run_server(host="0.0.0.0", port=self.config.get("port"), debug=self.config.get("debug")) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue