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(
|
||||||
|
@ -215,8 +228,8 @@ class HCDash:
|
||||||
dcc.Slider(id='slider-min', min=0, max=round(time.time()), step=600,
|
dcc.Slider(id='slider-min', min=0, max=round(time.time()), step=600,
|
||||||
value=0 ),
|
value=0 ),
|
||||||
], style={'marginLeft': '5em', 'marginRight': '3em'}
|
], style={'marginLeft': '5em', 'marginRight': '3em'}
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
dbc.Col([
|
dbc.Col([
|
||||||
html.Div(id='slider-max-txt', style={'marginLeft': '3em', 'marginRight':
|
html.Div(id='slider-max-txt', style={'marginLeft': '3em', 'marginRight':
|
||||||
'3em'}),
|
'3em'}),
|
||||||
|
@ -224,52 +237,28 @@ class HCDash:
|
||||||
dcc.Slider(id='slider-max', min=0, max=round(time.time()), step=600,
|
dcc.Slider(id='slider-max', min=0, max=round(time.time()), step=600,
|
||||||
value=round(time.time())),
|
value=round(time.time())),
|
||||||
], style={'marginLeft': '3em', 'marginRight': '3em'}
|
], style={'marginLeft': '3em', 'marginRight': '3em'}
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
dbc.Col([
|
dbc.Col([
|
||||||
html.Div(id='slider-limit-txt', style={'marginLeft': '3em', 'marginRight': '5em'}),
|
html.Div(id='slider-limit-txt', style={'marginLeft': '3em', 'marginRight': '5em'}),
|
||||||
html.Div([
|
html.Div([
|
||||||
dcc.Slider(id='slider-limit', min=0, max=1000, step=10, value=0 ),
|
dcc.Slider(id='slider-limit', min=0, max=1000, step=10, value=0 ),
|
||||||
], style={'marginLeft': '3em', 'marginRight': '5em'}
|
], style={'marginLeft': '3em', 'marginRight': '5em'}
|
||||||
),
|
|
||||||
])
|
|
||||||
]),
|
|
||||||
]
|
|
||||||
|
|
||||||
@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")
|
])
|
||||||
]
|
]),
|
||||||
|
]
|
||||||
|
res = self.get_sensor_values(sensorId, 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 "values" in res:
|
||||||
|
min_ts = int(res["values"][0]["ts"])
|
||||||
|
# sensor_data, min: [min, cur, max], max: [min, max, max]
|
||||||
|
return sensor_data, min_ts, cur_ts, max_ts, min_ts, max_ts, max_ts
|
||||||
|
|
||||||
|
|
||||||
## 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
|
|
||||||
# default last 7 days
|
|
||||||
cur_ts = round(time.time() - (60*60*24*7))
|
|
||||||
max_ts = int(time.time())
|
|
||||||
sensorType = None
|
|
||||||
if "values" in res:
|
|
||||||
min_ts = int(res["values"][0]["ts"])
|
|
||||||
sensorType = res["sensorType"]
|
|
||||||
return min_ts, cur_ts, max_ts
|
|
||||||
|
|
||||||
@app.callback(
|
@app.callback(
|
||||||
Output('slider-min-txt', 'children'),
|
Output('slider-min-txt', 'children'),
|
||||||
[Input('slider-min', 'value')])
|
[Input('slider-min', 'value')])
|
||||||
|
@ -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…
Reference in a new issue