Commit 37657163 authored by Michael Ott's avatar Michael Ott
Browse files

Initial import of SysFS MQTT agent

parent 8b5f03ab
CXXFLAGS = -O2 -g -Wall -Werror -I../include
OBJS = sysfsagent.o helper.o
LIBS = -L../lib -lrudeconfig -lmosquitto -lssl -lcrypto -lpthread
TARGET = sysfsagent
$(TARGET): $(OBJS)
$(CXX) -o $(TARGET) $(OBJS) $(LIBS)
all: $(TARGET)
clean:
rm -f $(OBJS) $(TARGET)
#include "helper.h"
#include <sys/time.h>
#include <stddef.h>
uint64_t getMsTime() {
struct timeval t;
if (gettimeofday(&t, NULL) == 0)
return t.tv_sec * 1000 + t.tv_usec / 1000;
else
return 0;
}
#ifndef HELPER_H_
#define HELPER_H_
#include <stdint.h>
uint64_t getMsTime();
#endif /* HELPER_H_ */
broker = localhost
[Sensor1]
path = /sys/devices/platform/coretemp.0/temp1_input
interval = 1000
[Sensor2]
path = /sys/devices/platform/coretemp.0/temp2_input
interval = 2000
[Sensor3]
path = /sys/devices/platform/coretemp.0/temp3_input
#include <iostream>
#include <vector>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <csignal>
#include <cerrno>
#include <unistd.h>
#include <rude/config.h>
#include <mosquitto.h>
#include "helper.h"
using namespace std;
typedef struct {
string name;
string path;
FILE* file;
int interval;
uint64_t nextRead;
} sensor_t;
vector<sensor_t> sensorList;
string broker;
int keepRunning = 1;
void sigHandler(int sig) {
keepRunning = 0;
}
int readConfiguration(string configFileName) {
rude::Config config;
if (config.load(configFileName.c_str())) {
for (int i = 0; i < config.getNumSections(); i++) {
const char* sectionName = config.getSectionNameAt(i);
if (strlen(sectionName) == 0) {
config.setSection(sectionName);
for (int j = 0; j < config.getNumDataMembers(); j++) {
const char* dataName = config.getDataNameAt(j);
if (strcasecmp(dataName, "broker") == 0) {
broker = config.getStringValue(dataName);
cout << "Broker: " << broker << endl;
} else {
cerr << "Unknown configuration parameter \"" << dataName << "\"";
}
}
} else {
sensor_t sensorConfig;
sensorConfig.name = sectionName;
sensorConfig.path = "";
sensorConfig.interval = 1000;
config.setSection(sectionName);
for (int j = 0; j < config.getNumDataMembers(); j++) {
const char* dataName = config.getDataNameAt(j);
if (strcasecmp(dataName, "path") == 0) {
sensorConfig.path = config.getStringValue(dataName);
} else if (strcasecmp(dataName, "interval") == 0) {
sensorConfig.interval = config.getIntValue(dataName);
}
}
cout << "Sensor \"" << sensorConfig.name << "\"" << endl;
cout << " Path : " << sensorConfig.path << endl;
cout << " Interval: " << sensorConfig.interval << endl;
sensorList.push_back(sensorConfig);
}
}
} else {
cerr << "Error reading configuration file: " << configFileName << endl;
}
config.clear();
return 0;
}
int main(int argc, char** argv) {
readConfiguration(argv[1]);
int mosqMajor, mosqMinor, mosqRevision;
mosquitto_lib_version(&mosqMajor, &mosqMinor, &mosqRevision);
cout << "mosquitto " << mosqMajor << "." << mosqMinor << "." << mosqRevision << endl;
mosquitto_lib_init();
char hostname[256];
if (gethostname(hostname, 255) != 0) {
fprintf(stderr, "Cannot get hostname.\n");
exit(EXIT_FAILURE);
}
hostname[255] = '\0';
cout << "Hostname: " << hostname << endl;
string clientId(hostname);
clientId.append("/");
struct mosquitto* mosq;
mosq = mosquitto_new(clientId.c_str(), false, NULL);
if (!mosq) {
perror(NULL);
exit(EXIT_FAILURE);
}
cout << "Connecting to broker: " << broker << endl;
if (mosquitto_connect(mosq, broker.c_str(), 1883, 1000) != MOSQ_ERR_SUCCESS) {
perror("\nCould not connect to host");
exit(EXIT_FAILURE);
}
signal(SIGINT, sigHandler);
char buf[1024];
uint64_t currentTime = getMsTime();
uint64_t nextWakeUp = currentTime;
for (unsigned int i = 0; i < sensorList.size(); i++) {
sensorList[i].file = fopen(sensorList[i].path.c_str(), "r");
if (sensorList[i].file == NULL) {
cerr << "Error opening sensor \"" << sensorList[i].name << "\": " << strerror(errno) << endl;
}
sensorList[i].nextRead = currentTime;
}
while (keepRunning) {
uint64_t sleepTime = nextWakeUp - currentTime;
cout << endl << "Next wakeup will be in " << sleepTime << "ms." << endl;
usleep(sleepTime * 1000);
currentTime = getMsTime();
for (unsigned int i = 0; i < sensorList.size(); i++) {
if (sensorList[i].nextRead >= nextWakeUp - sensorList[i].interval / 100
&& sensorList[i].nextRead <= nextWakeUp + sensorList[i].interval / 100) {
fseek(sensorList[i].file, 0, SEEK_SET);
fread(buf, 1024, 1, sensorList[i].file);
buf[strlen(buf)-1] = 0;
cout << "[" << currentTime << "] " << sensorList[i].name << ": \"" << buf << "\""<< endl;
stringstream ss;
ss << currentTime << " " << buf;
if (mosquitto_publish(mosq, NULL, (clientId + sensorList[i].name).c_str(), ss.str().size(), ss.str().c_str(), 0, false) != MOSQ_ERR_SUCCESS) {
cerr << "Warning: cannot send message." << endl;
}
sensorList[i].nextRead = currentTime + sensorList[i].interval;
if (sensorList[i].nextRead < nextWakeUp) {
nextWakeUp = sensorList[i].nextRead;
}
}
}
nextWakeUp = sensorList[0].nextRead;
for (unsigned int i = 0; i < sensorList.size(); i++) {
if (sensorList[i].nextRead < nextWakeUp) {
nextWakeUp = sensorList[i].nextRead;
}
}
}
for (unsigned int i = 0; i < sensorList.size(); i++) {
fclose(sensorList[i].file);
}
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment