Get vars with config + generic _float remove

This commit is contained in:
l_samenv
2024-08-19 11:02:32 +02:00
parent 8959e4a520
commit 9d032be0d2
4 changed files with 170 additions and 4 deletions

28
chart_config.py Normal file
View File

@ -0,0 +1,28 @@
from configparser import ConfigParser
class ChartConfig:
def __init__(self):
cfgp = ConfigParser()
cfgp.read("./variables_config.ini")
self.chart_config = cfgp["chart"]
def get_variable_parameter_config(self, key):
config = {}
positionnal = ["cat", "color", "unit"]
if key in self.chart_config.keys():
raw_value = self.chart_config[key]
arguments = raw_value.split(",")
keyword_mode = False
for i, argument in enumerate(arguments):
pieces = argument.split(":")
if len(pieces) == 2:
keyword_mode = True
config[pieces[0]] = pieces[1]
else:
if not keyword_mode: #everything is going well
config[positionnal[i]] = pieces[0]
else: #we cannot have a positionnal argument after a keyword argument
return None
return config
else:
return None

View File

@ -1,5 +1,6 @@
from influxdb_client import InfluxDBClient
from configparser import ConfigParser
from chart_config import ChartConfig
import ast
from datetime import datetime
@ -73,6 +74,29 @@ class InfluxDataGetter:
res = self._group_variables_by_unit(available_variables)
return res
def get_available_variables_at_time2(self, times, all=False):
"""
Gets the available variables (those that we can have a value for since the device has been installed on the instrument) at the given point in time.
We can get the last available variables at the given point in time or all the known variables for the day corresponding to the timestamp.
Parameters :
times ([int]) : the unix timestamps in seconds of the range. The first value can be unused. The last can represent the point in time.
all (bool) : indicates if we want all the variables for the given times[1] timestamp (all the day)
Returns :
[{"tag":(str), "unit":(str), "curves":[{"name":(str), "label":(str), "color":(str)}]}] : a list of dictionnaries, each one representing
a block of curves with their name, their label and their color to display, grouped by their tag (which can be the unit augmented with an index) and their unit.
"""
all_setup_info = self._get_all_setup_info_as_dict(times, all)
available_variables = self._extract_variables2(all_setup_info)
available_variables = self._filter_params_with_config(available_variables)
available_variables = self._remove_variables_params_wihout_param_float_and_split(available_variables, times)
res = self._group_variables_by_unit2(available_variables)
return res
def get_curves_in_timerange(self, variables, time, interval = None):
"""
@ -207,6 +231,43 @@ class InfluxDataGetter:
added_names.append(name)
return available_varirables
def _extract_variables2(self, all_setup_info_dict):
"""
Extracts relevant information out of the setup_info dict for each available variable in measurements nicos/se_main, nicos/se_stick, nicos/se_addons
Parameters :
all_setup_info_dict ([{(str):((str), {...})}]) : an array of the parsed "setup_info dict" of each measurements. The key is the secop_module prefixed with "se_", and the value is a tuple with its first value
being the type of Secop device for this module, and the value is too big to give its signature. Some tuple examples can be found under graphs/setup_info_examples.
Returns :
[{"name":(str), "label":(str), "unit":(str), "has_potential_target":(bool)}] : an array of dictionnaries, each containing the Influx name of the corresponding variable out of the setup_info dict,
the label to display in the Web GUI, its unit and a boolean value indicating if the variable has a potential target available.
"""
available_varirables = []
added_names = []
for setup_info_dict in all_setup_info_dict:
for (_, content) in setup_info_dict.items():
if content[0] != "nicos.devices.secop.devices.SecopDevice":
name = self._transform_secop_module_name_to_influx(content[1]["secop_module"])
if name not in added_names:
variable = {
"name":name,
"label":content[1]["secop_module"],
"params":{"value":{"cat":"", "color":"", "unit":content[1]["unit"]}} # main value
}
for param_name, param_content in content[1]["params_cfg"].items():
variable["params"][param_name] = {
"cat":"",
"color":"",
"unit":param_content["unit"] if "unit" in param_content.keys() else "" #unit might not be there
}
available_varirables.append(variable)
added_names.append(name)
return available_varirables
def _transform_secop_module_name_to_influx(self, secop_module_name):
"""
Transforms the name of the variable available in the setup_info dict into the Influx name.
@ -220,6 +281,48 @@ class InfluxDataGetter:
"""
return self._influx_instrument_config["measurement_prefix"] + secop_module_name.lower()
def _filter_params_with_config(self, available_variables):
chart_config = ChartConfig()
for variable in available_variables:
params = list(variable["params"].keys())
for param_key in params:
key = variable["label"] if param_key == "value" else variable["label"]+"."+param_key
param_config = chart_config.get_variable_parameter_config(key)
if param_config == None : # no entries were found
if param_key != "target" and param_key != "value": # and the current param is not value or target which are displayed by default
del variable["params"][param_key]
else:
if "cat" in param_config.keys() and param_config["cat"] == "None": # cat might not have been indicated
del variable["params"][param_key]
else:
for key, value in param_config.items():
variable["params"][param_key][key] = value
return available_variables
def _remove_variables_params_wihout_param_float_and_split(self, available_variables, times):
res = []
for variable in available_variables:
query = f"""
import "influxdata/influxdb/schema"
schema.measurementFieldKeys(bucket: "{self._bucket}", measurement: "{variable["name"]}", start:0, stop: {times[1] + 1})
|> yield(name: "res")
"""
records = self._db.query(query)[0].records
fields = [record.get_value() for record in records]
for param in variable["params"].keys():
if param+"_float" in fields:
res.append({
"name": variable["name"] if param == "value" else variable["name"]+"."+param,
"label": variable["label"] if param == "value" else variable["label"]+"."+param,
"cat": variable["params"][param]["cat"],
"color": variable["params"][param]["color"],
"unit": variable["params"][param]["unit"]
})
return res
def _remove_variables_without_value_float(self, available_variables, times):
"""
Removes some of the previously identified available_variables if they effectively do not have a value_float field in InfluxDB.
@ -273,6 +376,43 @@ class InfluxDataGetter:
return available_variables
def _group_variables_by_unit2(self, available_variables):
"""Performs a group by unit, while removing useless information and adding target curves.
Parameters :
available_variables ([{"name":(str), "label":(str), "unit":(str), "has_potential_target":(bool)}]) : an array of dictionnaries, each containing the Influx name of the corresponding variable out of the setup_info dict,
the label to display in the Web GUI, its unit and a boolean value indicating if the variable has a target available.
Returns :
[{"tag":(str), "unit":(str), "curves":[{"name":(str), "label":(str), "color":(str)}]] : a list of dictionnaries, each one representing
a block of curves with their name, their label and their color to display, grouped by their tag (which can be the unit augmented with an index) and their unit.
"""
groups = {}
for available_variable in available_variables:
self._append_variable2(groups, available_variable)
return list(groups.values())
def _append_variable2(self, groups, variable):
"""
Appends the variable in the unit group with a tag and a color, and creates the unit key if not available.
Parameters :
groups ({}) : a dictionnary that contains the curves grouped by unit, which will be updated
variable ({"name":(str), "label":(str), "unit":(str)[,"has_potential_target":(bool)]}) : a dictionnary containing the Influx name of the corresponding variable out of the setup_info dict,
the label to display in the Web GUI, its unit and possibly a boolean value indicating if the variable has a target available.
"""
key = variable["cat"]+variable["unit"]
if key not in groups.keys():
groups[key] = {"tag":key, "unit":variable["unit"], "curves":[]} #tag is set to cat+unit while client is not modified
groups[key]["curves"].append({
"name":variable["name"],
"label":variable["label"],
"color":variable["color"],
})
def _group_variables_by_unit(self, available_variables):
"""Performs a group by unit, while removing useless information and adding target curves.

View File

@ -138,7 +138,7 @@ class InfluxGraph:
start_time = int(self.get_abs_time(time)[0])
end_time = int(self.get_abs_time(time)[-1])
blocks = self.influx_data_getter.get_available_variables_at_time([start_time, end_time], all)
blocks = self.influx_data_getter.get_available_variables_at_time2([start_time, end_time], all)
# updates the self.variables attribute to keep track of the available variables
self.variables = [variable["name"] for block in blocks for variable in block["curves"]]

View File

@ -1,3 +1 @@
[chart]
T_stat.raw=cat:rawOhm
T_stat=color:#FF0000
[chart]