dcdbcsvimport.cpp 3.69 KB
Newer Older
1
/*
2
 * dcdbcsvimport.cpp
3
 *
4
5
 *  Created on: Apr 13, 2016
 *      Author: Axel Auweter & Michael Ott
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
 */

#include <iostream>
#include <cstdio>
#include <cstdint>
#include <cmath>
#include <fstream>
#include <iomanip> 
#include <sstream> 
#include <vector> 
#include <boost/tokenizer.hpp>
#include <algorithm>
#include <exception>

#include <pthread.h>

#include <dcdb/connection.h>
#include <dcdb/sensorconfig.h>
#include <dcdb/sensordatastore.h>
#include <dcdb/sensorid.h>
#include <dcdb/timestamp.h>
#include <dcdb/c_api.h>

typedef struct {
	std::string name;
	std::string topic;
	std::string publicName;
} sensor_t;

int main(int argc, char** argv)
{
  /* Connect to the data store */
  std::cout << std::endl;
  std::cout << "Connecting to the data store..." << std::endl;

  DCDB::Connection* connection;
  connection = new DCDB::Connection();
  connection->setHostname("127.0.0.1");
  if (!connection->connect()) {
      std::cout << "Cannot connect to database." << std::endl;
      return 1;
  }

  /* Initialize the SensorConfig and SensorDataStore interfaces */
  DCDB::SensorConfig sensorConfig(connection);
  DCDB::SensorDataStore sensorDataStore(connection);

  std::ifstream fs;
  std::string s;
  std::vector<std::string> vec;
  std::vector<sensor_t> sensors;
57
  std::string csvFilename = argv[1];
58
  std::string prefix = argv[2];
59
  uint64_t lineno = 0;
60

61
62
63
64
65
  /* Read header line from CSV to obtain sensor names and topics */
  std::cout << std::endl;
  std::cout << "Parsing CSV file: " << csvFilename << std::endl;
  std::cout << "Using sensor name prefix: " << prefix << std::endl;
  fs.open (csvFilename, std::fstream::in);
66
  std::getline(fs, s);
67
  lineno++;
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
  boost::tokenizer<boost::escaped_list_separator<char> > tk(s, boost::escaped_list_separator<char>('\\', ',', '\"'));
  int topics = 0;
  for (boost::tokenizer<boost::escaped_list_separator<char> >::iterator i=tk.begin(); i!=tk.end();++i) 
  {
	  if (i == tk.begin()) {
		  continue;
	  }
	sensor_t sensor;
	sensor.name = *i;
	std::stringstream ss;
	if (prefix.size() < 12) {
		ss << std::setfill('0') << std::setw((12-prefix.size())*2) << "";
	}
	const char *c = prefix.substr(0, 12).c_str();
	while (*c) {
		uint32_t x = *c++;
		ss << std::setfill('0') << std::setw(2) << std::hex << x;
	}
	ss << "/" << std::setfill('0') << std::setw(8) << std::hex << topics;
	sensor.topic = ss.str();
	sensor.publicName = prefix + "." + sensor.name;
	std::replace(sensor.publicName.begin(), sensor.publicName.end(), ' ', '_');
	sensors.push_back(sensor);
    topics++;
  }
  
94
  /* Read actual sensor readings */
95
96
  while (std::getline(fs, s)) {
    int col = 0;
97
98
    lineno++;
	DCDB::TimeStamp ts;
99
100
101
102
	boost::tokenizer<boost::escaped_list_separator<char> > tk(s, boost::escaped_list_separator<char>('\\', ',', '\"'));
    for (boost::tokenizer<boost::escaped_list_separator<char> >::iterator i=tk.begin(); i!=tk.end();++i) 
    {
		if (0 == col) {
103
			ts = DCDB::TimeStamp(*i);
104
		} else {
105
			// std::cout << ts.getRaw() << " " << sensors[col-1].topic << ":" << *i << std::endl;
106
107
			try {
				DCDB::SensorId sid(sensors[col-1].topic);
108
				sensorDataStore.insert(&sid, ts.getRaw(), std::stoll(*i));
109
110
			}
			catch (std::exception &e) {
111
				std::cerr << "Error parsing CSV line " << lineno << " column " << col+1 << ": \"" << *i << "\"" << std::endl;
112
113
114
115
116
			}
		}
		col++;
    }	  
  }
117
118
  
  fs.close();
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

  /* Create public sensor names */
  std::cout << std::endl;
  std::cout << "Publishing sensors..." << std::endl;

  std::vector<sensor_t>::iterator it;
  for (it = sensors.begin(); it != sensors.end(); it++) {
	  std::cout << it->name << " " << it->topic << " " << it->publicName << std::endl;
	  sensorConfig.publishSensor(it->publicName.c_str(), it->topic.c_str());
  }

  /* Disconnect */
  delete connection;

  return 0;
}