164 lines
4.0 KiB
C
164 lines
4.0 KiB
C
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
|
|
#include <mosquitto.h>
|
|
#include <modbus/modbus.h>
|
|
|
|
#include "sdm.h"
|
|
#include "config.h"
|
|
|
|
|
|
int main(int argc, char **argv) {
|
|
int nmeters, i, err;
|
|
|
|
struct mosquitto *mosq;
|
|
modbus_t *mb;
|
|
sdm_t **sdms;
|
|
FILE **logfiles;
|
|
|
|
char *printme;
|
|
char buf[4096];
|
|
|
|
mosquitto_lib_init();
|
|
mosq = mosquitto_new(cfg.mosq_name, false, NULL);
|
|
|
|
if (mosq == NULL) {
|
|
//FIXME
|
|
|
|
return -1;
|
|
}
|
|
|
|
err = mosquitto_connect(mosq, cfg.mosq_host, cfg.mosq_port, cfg.mosq_keepalive);
|
|
|
|
if (err != MOSQ_ERR_SUCCESS) {
|
|
//FIXME
|
|
|
|
return -1;
|
|
}
|
|
|
|
mb = modbus_new_rtu(cfg.ser_device, cfg.ser_baud, cfg.ser_parity, cfg.ser_databits, cfg.ser_stopbits);
|
|
|
|
if (mb == NULL) {
|
|
fprintf(stderr, "%s:%d: failed to create Modbus Context\n", __FILE__, __LINE__);
|
|
|
|
return -1;
|
|
}
|
|
|
|
if (modbus_connect(mb) == -1) {
|
|
fprintf(stderr, "%s:%d: Modbus connection failed: %s\n", __FILE__, __LINE__, modbus_strerror(errno));
|
|
return -2;
|
|
}
|
|
|
|
nmeters = 0;
|
|
while (cfg.meters[nmeters].friendlyname != NULL) {
|
|
nmeters++;
|
|
}
|
|
|
|
sdms = (sdm_t **)calloc(sizeof(sdm_t *) * nmeters, 1);
|
|
logfiles = (FILE **)calloc(sizeof(FILE *) * nmeters, 1);
|
|
|
|
for (i = 0; i < nmeters; i++) {
|
|
err = 0;
|
|
sdms[i] = sdm_new(mb, cfg.meters[i].addr, cfg.meters[i].friendlyname, cfg.meters[i].type, &err);
|
|
|
|
if (sdms[i] == NULL) {
|
|
fprintf(stderr, "%s:%d: Failed to create meter %s\n", __FILE__, __LINE__, cfg.meters[i].friendlyname);
|
|
}
|
|
|
|
snprintf(buf, 4095, "logs/%s.log", sdms[i]->friendlyname);
|
|
logfiles[i] = fopen(buf, "r");
|
|
if (logfiles[i] == NULL) {
|
|
char *header;
|
|
|
|
logfiles[i] = fopen(buf, "a");
|
|
if (logfiles[i] == NULL) {
|
|
fprintf(stderr, "%s:%d: Failed to open logfile %s:\n", __FILE__, __LINE__, cfg.meters[i].friendlyname);
|
|
perror("");
|
|
}
|
|
|
|
if (sdm_print_csv_header(sdms[i], &header)) {
|
|
//FIXME
|
|
}
|
|
|
|
fprintf(logfiles[i], "%s\n", header);
|
|
free(header);
|
|
} else {
|
|
logfiles[i] = freopen(buf, "a", logfiles[i]);
|
|
}
|
|
|
|
if (logfiles[i] == NULL) {
|
|
fprintf(stderr, "%s:%d: Failed to open logfile %s:\n", __FILE__, __LINE__, cfg.meters[i].friendlyname);
|
|
perror("");
|
|
}
|
|
}
|
|
|
|
while (1) {
|
|
for (i = 0; i < nmeters; i++) {
|
|
if (sdm_update(sdms[i]) != SDM_OK) {
|
|
int errsv = errno;
|
|
fprintf(stderr, "%s:%d: %s: %s (%d)\n", __FILE__, __LINE__, modbus_strerror(errsv), sdms[i]->friendlyname, sdms[i]->address);
|
|
if (errsv == ECONNRESET || errsv == EBADF) {
|
|
// USB Connection failed?
|
|
// try to reconnect...
|
|
modbus_close(mb);
|
|
if (modbus_connect(mb) == -1) {
|
|
fprintf(stderr, "%s:%d: Modbus reconnect failed: %s\n", __FILE__, __LINE__, modbus_strerror(errno));
|
|
sleep(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sdm_print_csv(sdms[i], &printme) != SDM_OK) {
|
|
fprintf(stderr, "%s:%d: error in sdm_print_csv!\n", __FILE__, __LINE__);
|
|
} else {
|
|
fprintf(logfiles[i], "%s\n", printme);
|
|
fflush(logfiles[i]);
|
|
free(printme);
|
|
}
|
|
if (sdm_print_json(sdms[i], &printme) != SDM_OK) {
|
|
fprintf(stderr, "%s:%d: error in sdm_print_json!\n", __FILE__, __LINE__);
|
|
} else {
|
|
int err;
|
|
//FIXME
|
|
char topic[256];
|
|
|
|
snprintf(topic, 255, "%s/%s", cfg.mosq_topicprefix, sdms[i]->friendlyname);
|
|
|
|
err = mosquitto_publish(mosq, NULL, topic, strlen(printme), printme, 0, false);
|
|
if (err != MOSQ_ERR_SUCCESS) {
|
|
fprintf(stderr, "%s:%d: mosquitto error! (%d)\n", __FILE__, __LINE__, err);
|
|
err = mosquitto_reconnect(mosq);
|
|
if (err != MOSQ_ERR_SUCCESS) {
|
|
//FIXME
|
|
fprintf(stderr, "%s:%d: Mosquitto reconnect failed.\n", __FILE__, __LINE__);
|
|
}
|
|
|
|
err = mosquitto_publish(mosq, NULL, topic, strlen(printme), printme, 0, false);
|
|
if (err != MOSQ_ERR_SUCCESS) {
|
|
//FIXME
|
|
fprintf(stderr, "%s:%d: publish failed after reconnect.\n", __FILE__, __LINE__);
|
|
}
|
|
}
|
|
free(printme);
|
|
}
|
|
usleep(10000);
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < nmeters; i++) {
|
|
sdm_free(sdms[i]);
|
|
fclose(logfiles[i]);
|
|
}
|
|
free(logfiles);
|
|
free(sdms);
|
|
modbus_close(mb);
|
|
//broken: "free(): double free detected in tcache 2"
|
|
//modbus_free(mb);
|
|
|
|
mosquitto_lib_cleanup();
|
|
|
|
return 0;
|
|
}
|
|
|