Source code for datalogd.plugins.csv_datafilter

from datalogd import DataFilter, listify

[docs]class CSVDataFilter(DataFilter): """ Format received data into a table of comma separated values. The column headers can be formatted using values from the data. For example, for the data:: [ {'type': 'temperature', 'id': '0', 'value': 22.35}, {'type': 'humidity', 'id': '0', 'value': 55.0}, {'type': 'temperature', 'id': '1', 'value': 25.80}, ] and a node initialised using:: sink [class=CSVDataSink keys="['value']", labels="['{type}_{id}'"]; the output will be:: temperature_0,humidity_0,temperature_1 22.35,55.0,25.80 Setting ``labels`` to ``None`` will disable the column headers. By default, the column headers will be generated on every receipt of data. To instead output the column headers only once on the first receipt of data, use the parameter ``header="once"``. Setting ``header=None`` will also disable the headers completely. :param keys: Name of data keys to format into columns of the CSV. :param labels: Labels for the column headers, which may contain mappings to data values. :param header: Display the column header ``"once"`` or ``"every"`` or ``None``. """ def __init__(self, sinks=[], keys=["timestamp", "value"], labels=["timestamp", "{type}_{id}"], header="every"): super().__init__(sinks=sinks) self.keys = keys self.labels = labels self._generate_header = header
[docs] def receive(self, data): """ Accept ``data`` and format into a table of CSV. :param data: Data to format as CSV. """ data = listify(data) # Generate column headers col_labels = [] cols = [] for d in data: if self.keys and isinstance(d, dict): # May be inefficient, but orders keys as requested for k_i, k in enumerate(self.keys): for dk in d.keys(): if k == dk: if self.labels: col_labels.append(self.labels[k_i].format_map(d)) cols.append(listify(d[k])) else: if self.labels: col_labels.append("data") cols.append(d) if len(data) > 0: csv = "" if self._generate_header in ("once", "every"): # Generate column header if self.labels: csv += ",".join(col_labels) + "\n" if self._generate_header == "once": # Generate header once on first data receipt self._generate_header = None # Generate row from data for r_i in range(min(len(x) for x in cols)): csv += ",".join([str(col[r_i]) for col in cols]) + "\n" self.send(csv.rstrip("\n"))