# Path: kotori/io/protocol/util.py
# def parse_timestamp(timestamp):
# 
#     if isinstance(timestamp, text_type):
# 
#         # FIXME: Maybe use system timezone here by default.
#         # TODO: Make configurable via channel settings.
# 
#         # HACK: Assume CET (Europe/Berlin) for human readable timestamp w/o timezone offset
#         qualified = any([token in timestamp for token in ['Z', '+', ' CET', ' CEST']])
#         if not qualified:
#             timestamp += ' CET'
# 
#         # Parse datetime string
#         # Remark: Maybe use pandas.tseries.tools.parse_time_string?
#         # TODO: Cache results of call to gettz to improve performance
#         berlin = gettz('Europe/Berlin')
#         tzinfos = {'CET': berlin, 'CEST': berlin}
#         timestamp = parse(timestamp, tzinfos=tzinfos)
# 
#     return timestamp
# 
# def is_number(s):
#     """
#     Check string for being a numeric value.
#     http://pythoncentral.io/how-to-check-if-a-string-is-a-number-in-python-including-unicode/
#     """
#     try:
#         float(s)
#         return True
#     except ValueError:
#         pass
# 
#     try:
#         import unicodedata
#         unicodedata.numeric(s)
#         return True
#     except (TypeError, ValueError):
#         pass
# 
#     return False
# 
# def convert_floats(data, integers=None):
#     """
#     Convert all numeric values in dictionary to float type.
#     """
#     integers = integers or []
#     delete_keys = []
#     for key, value in data.items():
#         try:
#             if isinstance(value, datetime.datetime):
#                 continue
#             if is_number(value):
#                 if key in integers:
#                     data[key] = int(value)
#                 else:
#                     data[key] = float(value)
#             if math.isnan(data[key]):
#                 delete_keys.append(key)
#         except:
#             pass
# 
#     for key in delete_keys:
#         del data[key]
# 
#     return data


import math
import requests
from copy import deepcopy
from funcy import project
from collections import OrderedDict
from twisted.logger import Logger
from influxdb.client import InfluxDBClient, InfluxDBClientError
from kotori.io.protocol.util import parse_timestamp, is_number, convert_floats
                    if is_number(chunk['time']):
                        chunk['time'] = float(chunk['time'])

                    # Remove timestamp from data payload.
                    del data[time_field]

                    # If we found a timestamp field already,
                    # don't look out for more.
                    break

        # Extract geohash from data. Finally, thanks Rich!
        # TODO: Also precompute geohash with 3-4 different zoomlevels and add them as tags
        if "geohash" in data:
            chunk["tags"]["geohash"] = data["geohash"]
            del data['geohash']

        if "latitude" in data and "longitude" in data:
            chunk["tags"]["latitude"] = data["latitude"]
            chunk["tags"]["longitude"] = data["longitude"]
            del data['latitude']
            del data['longitude']

        # Extract more information specific to luftdaten.info
        for field in ['location', 'location_id', 'location_name', 'sensor_id', 'sensor_type']:
            if field in data:
                chunk["tags"][field] = data[field]
                del data[field]

        # TODO: Maybe do this at data acquisition / transformation time, not here.
        if 'time' in chunk:

# Path: kotori/io/protocol/util.py
# def parse_timestamp(timestamp):
# 
#     if isinstance(timestamp, text_type):
# 
#         # FIXME: Maybe use system timezone here by default.
#         # TODO: Make configurable via channel settings.
# 
#         # HACK: Assume CET (Europe/Berlin) for human readable timestamp w/o timezone offset
#         qualified = any([token in timestamp for token in ['Z', '+', ' CET', ' CEST']])
#         if not qualified:
#             timestamp += ' CET'
# 
#         # Parse datetime string
#         # Remark: Maybe use pandas.tseries.tools.parse_time_string?
#         # TODO: Cache results of call to gettz to improve performance
#         berlin = gettz('Europe/Berlin')
#         tzinfos = {'CET': berlin, 'CEST': berlin}
#         timestamp = parse(timestamp, tzinfos=tzinfos)
# 
#     return timestamp
# 
# def is_number(s):
#     """
#     Check string for being a numeric value.
#     http://pythoncentral.io/how-to-check-if-a-string-is-a-number-in-python-including-unicode/
#     """
#     try:
#         float(s)
#         return True
#     except ValueError:
#         pass
# 
#     try:
#         import unicodedata
#         unicodedata.numeric(s)
#         return True
#     except (TypeError, ValueError):
#         pass
# 
#     return False
# 
# def convert_floats(data, integers=None):
#     """
#     Convert all numeric values in dictionary to float type.
#     """
#     integers = integers or []
#     delete_keys = []
#     for key, value in data.items():
#         try:
#             if isinstance(value, datetime.datetime):
#                 continue
#             if is_number(value):
#                 if key in integers:
#                     data[key] = int(value)
#                 else:
#                     data[key] = float(value)
#             if math.isnan(data[key]):
#                 delete_keys.append(key)
#         except:
#             pass
# 
#     for key in delete_keys:
#         del data[key]
# 
#     return data


# Path: kotori/daq/storage/influx.py
import math
import requests
from copy import deepcopy
from funcy import project
from collections import OrderedDict
from twisted.logger import Logger
from influxdb.client import InfluxDBClient, InfluxDBClientError
from kotori.io.protocol.util import parse_timestamp, is_number, convert_floats

                    if is_number(chunk['time']):
                        chunk['time'] = float(chunk['time'])

                    # Remove timestamp from data payload.
                    del data[time_field]

                    # If we found a timestamp field already,
                    # don't look out for more.
                    break

        # Extract geohash from data. Finally, thanks Rich!
        # TODO: Also precompute geohash with 3-4 different zoomlevels and add them as tags
        if "geohash" in data:
            chunk["tags"]["geohash"] = data["geohash"]
            del data['geohash']

        if "latitude" in data and "longitude" in data:
            chunk["tags"]["latitude"] = data["latitude"]
            chunk["tags"]["longitude"] = data["longitude"]
            del data['latitude']
            del data['longitude']

        # Extract more information specific to luftdaten.info
        for field in ['location', 'location_id', 'location_name', 'sensor_id', 'sensor_type']:
            if field in data:
                chunk["tags"][field] = data[field]
                del data[field]

        # TODO: Maybe do this at data acquisition / transformation time, not here.
        if 'time' in chunk:

            timestamp = chunk['time'] = parse_timestamp(chunk['time'])