Esempio n. 1
0
class InfluxDataFrameReader:
    def __init__(self,
                 host='127.0.0.1',
                 port=8086,
                 user=None,
                 password=None,
                 dbname='db0',
                 interval='10m'):
        self.host = host
        self.port = port
        self.dbname = dbname
        self.user = user
        self.password = password
        self.ssl = False
        self.verify_ssl = False
        self.interval = interval
        # self.ssl = True if self.host != '127.0.0.1' else False
        # self.verify_ssl = True if self.host != '127.0.0.1' else False
        self.client = DataFrameClient(host=self.host,
                                      port=self.port,
                                      database=self.dbname,
                                      username=self.user,
                                      password=self.password,
                                      ssl=self.ssl,
                                      verify_ssl=self.verify_ssl)
        try:
            self._ver = self.client.ping()
            logger.info('Connected to DB {} version = {}'.format(
                self.dbname, self._ver))
        except Exception as error:
            self._ver = False
            logger.error('Connection error: {}'.format(error))

    def time_query(self, measurement='outdoor_weather', time_shift='1h'):
        if not self._ver:
            result = None
        else:
            query = "SELECT * FROM {} WHERE time > now() - {} AND time < now()".format(
                measurement, time_shift)
            try:
                result = self.client.query(
                    query, database=self.dbname).get(measurement)
            except influxdb.client.InfluxDBClientError as error:
                logger.error(
                    'Error while trying to query DB: {}'.format(error))
                result = None
        return result

    def read_results(self):
        _df_pv = self.time_query('pv_measurement', self.interval)
        _df_hp = self.time_query('hp_measurement', self.interval)
        df_pv = _df_pv.loc[:, ['power']]
        df_pv.columns = ['pv_power']
        df_hp = _df_hp.loc[:, [
            '0_set_temp', '1_sens_on', '2_sens_off', '3_hp_on_off',
            '4_hysteresis_on', '5_hysteresis_off'
        ]]
        return df_pv, df_hp
class InfluxServerIO:
    logger = logging.getLogger('influx_server_io')

    def __init__(self,
                 host=None,
                 database=None,
                 port=None,
                 username=None,
                 password=None):
        """
        Constructor.
        """
        self.logger.debug("Setting connection parameters")
        self.host = host
        self.database = database
        self.port = port
        self.username = username
        self.password = password

        self.client = None

    def connect(self):
        """
        Open connection.
        """
        try:
            self.logger.debug("Connecting to DB")

            self.client = DataFrameClient(self.host,
                                          self.port,
                                          self.username,
                                          self.password,
                                          self.database,
                                          timeout=15)
            self.client.ping()

            self.logger.debug("DB Connection set")
        except Exception as err:
            self.logger.error("DB Connection failed: " + str(err))
            raise Exception("DB Connection failed: " + str(err))

    def disconnect(self):
        """
        Close connection.
        """
        try:
            self.logger.debug("Closing DB connection")
            if self.client is not None:
                self.client.close()
            self.client = None
            self.logger.debug("DB Connection closed")
        except Exception as err:
            self.logger.error("Can't disconnect from DB: " + str(err))
            raise Exception("Can't disconnect from DB: " + str(err))

    def read_data(self,
                  device_id=None,
                  data_source_id=None,
                  time_upload=None,
                  limit=None):
        """
        Read data from db according to object's parameters.
        :param device_id: list of ids [uuid1, uuid2, ..., uuidN]
        :param data_source_id: list of ids [id1, id2, ..., idN]
        :param time_upload: list of tuples of dates [(d_min1 d_max1), (d_min2 d_max2), ..., (d_minN d_maxN)]
        :param limit: retrieved data rows limit
        :return: list of queries results
        """
        results = pd.DataFrame()
        try:
            self.logger.debug("Reading data")

            if limit is not None:
                self.logger.debug("Data reading limit set to " + str(limit))
                limit = "LIMIT " + str(limit)
            else:
                limit = ""

            for di, dsi, tu in zip(device_id, data_source_id, time_upload):

                params = {
                    "di": str(di),
                    "dsi": str(dsi),
                    "limit": limit,
                    "from": datetime.datetime.strftime(tu[0],
                                                       "%Y-%m-%dT%H:%M:%SZ"),
                    "to": datetime.datetime.strftime(tu[1],
                                                     "%Y-%m-%dT%H:%M:%SZ")
                }

                query = r"SELECT value FROM data WHERE device_id='{di}' ".format(
                    **params)
                query += r"and data_source_id='{dsi}' ".format(**params)
                query += r"and time >= '{from}' and time <= '{to}' ".format(
                    **params)
                query += r"{limit}".format(**params)

                self.logger.debug("Executing query " + str(query))

                result = self.client.query(query)
                name = str(di) + '_' + str(dsi)

                if len(result) != 0:
                    r = result['data']
                    self.logger.debug("Column " + name + " contains " +
                                      str(len(r)) + " rows")
                    r.rename(columns={"value": name}, inplace=True)
                    results = pd.merge(results,
                                       r,
                                       how='outer',
                                       left_index=True,
                                       right_index=True)
                else:
                    self.logger.debug("Column " + name + " contains " +
                                      str(0) + " rows")
                    results[name] = np.nan

        except Exception as err:
            self.logger.error("Impossible to read: " + str(err))
            raise Exception("Impossible to read: " + str(err))
        self.logger.debug("Reading complete: " + str(results.shape) +
                          " entries returned")
        return results

    def write_data(self, result_id=None, output_data=None):
        """
        Write data from this object to db.
        :param result_id: list of ids [uuid1, uuid2, ..., uuidK]
        :param output_data: DataFrame
        :return: list of result objects
        """
        self.logger.debug("Writing data")
        results = []
        try:
            for col, ri in zip(output_data.columns, result_id):
                df = pd.DataFrame(output_data[col])
                if col.startswith('bool'):
                    df.rename(columns={col: 'boolean'}, inplace=True)
                elif col.startswith('val'):
                    df.rename(columns={col: 'value'}, inplace=True)
                else:
                    self.logger.warning(
                        "Column name: " + str(col) +
                        " (doesnt's start with 'val' or 'bool', renaming to 'val')"
                    )
                    df.rename(columns={col: 'value'}, inplace=True)
                v = self.client.write_points(df, 'data_result',
                                             {'result_id': str(ri)})
                results.append(str(ri))
        except Exception as err:
            self.logger.error("Writing to DB failed: " + str(err))
            raise Exception("Writing to DB failed " + str(err))
        self.logger.debug("Writing to DB complete " + str(results))
        return results
Esempio n. 3
0
class InfluxConnection():
    """Influx DB API assistant Class."""
    def __init__(self,
                 db_host=DB_HOST,
                 db_port=DB_PORT,
                 db_username=DB_USERNAME,
                 db_password=DB_PASSWORD,
                 database=DB_NAME):

        self.host = db_host
        self.port = db_port
        self.username = db_username
        self.password = db_password
        self.database = database

        self.db_client = InfluxDBClient(host=self.host,
                                        port=self.port,
                                        username=self.username,
                                        password=self.password,
                                        database=self.database)
        self.wait_for_influxdb()

        self.df_client = DataFrameClient(host=self.host,
                                         port=self.port,
                                         username=self.username,
                                         password=self.password,
                                         database=self.database)
        self.wait_for_dataFrameClient()

    def wait_for_influxdb(self):
        """Function to wait for the influxdb service to be available."""
        try:
            self.db_client.ping()
            print(f"InfluxDBClient Connected | {datetime.now()}")
            return None
        except ConnectionError:
            print("InfluxDBClient Connection FAILED: Trying again (1s)")
            time.sleep(1)
            self.wait_for_influxdb()

    def wait_for_dataFrameClient(self):
        """Function to wait for the influxdb service to be available."""
        try:
            self.df_client.ping()
            print(f"DataFrameClient Connected | {datetime.now()} ")
            return None
        except ConnectionError:
            print("DataFrameClient Connection FAILED: Trying again (1s)")
            time.sleep(1)
            self.wait_for_dataFrameClient()

    def get_n_recent_readings(self,
                              number_of_readings,
                              table_name=DB_CONNECTOR_TABLE):
        query_to_execute = (
            'select * from "{}" group by * order by DESC limit {}').format(
                table_name, number_of_readings)

        return self.db_client.query(query_to_execute).raw['series']

    def get_n_recent_readings_with_condition(self,
                                             number_of_readings,
                                             adc,
                                             channel,
                                             table_name=DB_CONNECTOR_TABLE):
        query_to_execute = (
            'select * from "{}" where adc=\'{}\' and channel=\'{}\' group by *'
            ' order by DESC limit {}').format(table_name, adc, channel,
                                              number_of_readings)

        return self.db_client.query(query_to_execute).raw['series']

    def push_to_database(self, json_data, table_name="converted_measurements"):
        pass
Esempio n. 4
0
def print_data(in_q, break_q):
    # Setup Django environment
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    env = environ.Env()
    env_path = os.path.join(BASE_DIR, '.env')
    environ.Env.read_env('.env')

    # Create InfluxDb client
    DB_HOST = env('DB_HOST')
    DB_USER = env('DB_USER')
    DB_PASSWORD = env('DB_PASSWORD')

    print("Connecting to InfluxDB...")
    while True:

        if break_q.qsize() > 0:
            break_q.put(1)
            break

        try:
            client = DataFrameClient(host=DB_HOST,
                                     port='8086',
                                     username=DB_USER,
                                     password=DB_PASSWORD,
                                     database='mmbox')

            ping = client.ping()
            if ping:
                print("YES!")
                break
        except:
            continue

    print("Connected to InfluxDB v. " + ping)

    # listening for data to send
    while True:
        # check if keyboard interrupt has been detected in the main thread
        if break_q.qsize() > 0:
            break_q.put(1)
            break

        time.sleep(5)  # The delay in seconds between writes to the DB
        poses = in_q.get(
        )  # pop the data that's been put on "out_q" in the record_data function

        if len(
                poses
        ) > 0:  # Check if people are detected (and if the pose detection has started)

            timestamp = time.time()
            dtidx = pd.DatetimeIndex(
                data=[pd.to_datetime(timestamp, unit='s', origin='unix')],
                name='Time')
            df = pd.DataFrame(data=poses, index=dtidx, columns=poses)

            # Alternative way to get unix timestamp
            #times = [time.time()]
            #df = pd.DataFrame(data=output, index=pd.to_datetime(times, unit='s', origin='unix'), columns=output)

            try:
                client.write_points(
                    df, 'mmbox_video_pose',
                    batch_size=1000)  # send dataframe to InfluxDB
            except:
                print("Error writing to InfluxDB")

            print(df)

    print("Printer stopped")
Esempio n. 5
0
class DataCollector:

    def __init__(self, host, port, user, password, database):
        self.host = host
        self.port = port
        self.user = user
        self.password = password
        self.database = database
        try:
            self.client = DataFrameClient(host, port, user, password, database, timeout=30)
            self.client.ping()
            self.experimentIds = self.cache_experimentIds()
        except requests.exceptions.ConnectTimeout as e:  # Timeout of InfluxDB connection
            print(e)
            self.client = None


    def get_data(self, experimentId, measurements=[], fields=[], additional_clause=None, chunked=False, chunk_size=10000, limit=None, offset=None, max_lag="1s"):
        if not measurements:
            results = self.client.query(f"SHOW measurements WHERE (ExperimentId =~ /{experimentId}/ or ExecutionId =~ /{experimentId}/)")
            measurements = [item["name"] for item in results["measurements"]]
        measurements = ", ".join([f'"{item}"' for item in measurements])
        fields = ', '.join([f'"{item}"' for item in fields]) if fields else '*'
        limit = f' LIMIT {limit}' if limit else ''
        offset = f' OFFSET {offset}' if offset else ''
        if not additional_clause:
            additional_clause = ''
        df = self.query_df(f'SELECT {fields} FROM {measurements} WHERE (ExperimentId =~ /{experimentId}/ or ExecutionId =~ /{experimentId}/){additional_clause}{limit}{offset}')
        df = df.set_index('time')
        df.index = pd.to_datetime(df.index).floor(max_lag)
        df = df.mean(level=0)  # .dropna(axis=0)
        return df


    def get_experimentIds_for_measurement(self, measurement):
        result = self.client.query(f'SELECT distinct(ExecutionId) as ExecutionId from (SELECT * from "{measurement}")', chunked=False, chunk_size=1000, epoch='ns')
        return list(result[measurement].iloc[:, 0])


    def get_measurements_for_experimentId(self, experimentId):
        result = self.client.query(f'SHOW measurements WHERE ExecutionId =~ /{experimentId}/ or ExperimentId =~ /{experimentId}/', chunked=False, chunk_size=1000, epoch='ns')
        return [item["name"] for item in list(result['measurements'])]


    def cache_experimentIds(self):
        experimentIds = []
        measurements = [measurement['name'] for measurement in self.client.get_list_measurements()]
        for measurement in tqdm(measurements, desc="Getting ExecutionIds"):
            results = self.query_df(f'''SELECT distinct(ExecutionId) as ExecutionId from (SELECT * from "{measurement}")''')
            if not results.empty:
                experimentIds += list(results['ExecutionId'].astype(str))
        return sorted(list(set(experimentIds)))


    def query_df(self, query):
        data = {}
        data['db'] = self.database
        data['u'] = self.user
        data['p'] = self.password
        data['precision'] = 'ns'
        data['q'] = query
        url_values = urllib.parse.urlencode(data)
        url = f"http://{self.host}:{self.port}/query?" + url_values
        request = urllib.request.Request(url, headers={'Accept': 'application/csv'})
        response = urllib.request.urlopen(request)
        response_bytestr = response.read()
        if response_bytestr:
            return pd.read_csv(BytesIO(response_bytestr), sep=",", low_memory=False)
        else:
            return pd.DataFrame()


    def get_all_experimentIds(self):
        return self.experimentIds