from time import time as current_time import logging import json import io import uuid # from configparser import ConfigParser from math import ceil from sehistory.seinflux import fmtime from colors import assign_colors_to_curves from chart_config import ChartConfig from base import get_abs_time, HandlerBase def split_tags(tags): return {k: v.split(',') for k, v in tags.items()} class InfluxGraph(HandlerBase): """Class implementing the logic of the different routes that are called by the client to retrieve graph data with InfluxDB. Global constants : HISTORICAL (int) : value that represents the "historical" visualization mode, meaning that the most recent point is not in the visualisation window (no live data is sent). ACTUAL (int) : value that represents the "actual" visualization mode, wihch is an intermediate state used before going for live mode (the requested time window includes now) LIVE (int) : value that represents the "live" visualization mode, meaning that new points are sent to the client. Attributes : influx_data_getter (InfluxDataGetter) : the InfluxDataGetter instance that allows to get data out of InfluxDB. chart_configs ([ChartConfig]) : an array of chart configuration to apply when /getvars is called livemode (int) : the type of visualization the user is currently in. Can be HISTORICAL, ACTUAL or LIVE. end_query (int) : the unix timestamp in seconds of the most recent requested point in time of the last query or update. last_values ({(str):((int), (float))}) : a dictionnary where the keys are the variable names, and the values are tuples, where the first value is the unix timestamp of the most recent value known for this variable, and the second value its corresponding value variables ({(str):(str)}) : a dictionary of the current available variables requested by the client. The key is the InfluxDB name of the curve, and the value is its label in the GUI. """ HISTORICAL = 0 ACTUAL = 1 LIVE = 2 def __init__(self, server, instrument, device_name, tags): """create instance for retrieving history :param db: a database client (SEInflux instance) :param instrument: the name of anm instrument or None :param streams: a stream or comma separated list of streams :param devices: a device name ar a comma separated list of devices :param device_name: (comma separated) device name for labelling typically only one of the 3 last parameters are needed if more are specified, all of them must be fulfilled """ super().__init__() # put methods w_... to handlers self.handlers['graphpoll'] = self.graphpoll self.server = server self.db = server.db # self.influx_data_getter = influx_data_getter self.chart_configs = ["./config/generic.ini"] self.instrument = instrument self.device_name = device_name if instrument: # TODO: should it not be better to have inifiles per device? self.chart_configs.append(f"./config/{instrument}.ini") self.livemode = self.HISTORICAL self.last_values = {} # dict of last known point (