/* * modbuslog * * Copyright (C) 2011 Jonathan McCrohan * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // gcc modbuslog.c -o modbuslog `pkg-config --libs --cflags libmodbus libconfig` #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define SLAVE_ID 1 #define START_ADDRESS 0 #define NUMBER_REGISTERS 14 void minute_check(int signum) { alarm(60); } void find_mac(unsigned char* mac_address) { int s; struct ifreq ifr; s = socket(PF_INET, SOCK_DGRAM, 0); memset(&ifr, 0x00, sizeof(ifr)); strcpy(ifr.ifr_name, "eth0"); ioctl(s, SIOCGIFHWADDR, &ifr); close(s); unsigned char mac_address_internal[6]; sprintf(mac_address_internal, "%.2X%.2X%.2X%.2X%.2X%.2X", (unsigned char) ifr.ifr_hwaddr.sa_data[0], (unsigned char) ifr.ifr_hwaddr.sa_data[1], (unsigned char) ifr.ifr_hwaddr.sa_data[2], (unsigned char) ifr.ifr_hwaddr.sa_data[3], (unsigned char) ifr.ifr_hwaddr.sa_data[4], (unsigned char) ifr.ifr_hwaddr.sa_data[5]); strcpy(mac_address, mac_address_internal); } int main(int argc, char *argv[]) { const char *configfile = "modbuslog.cfg"; int DEBUG = 0; int k; for (k = 1; k < argc; k++) { if (strcmp(argv[k], "-d") == 0) { DEBUG = 1; } } config_t cfg; //config_setting_t *setting; unsigned char mac_address[6]; const char *modbus_device_address; int modbus_baud_rate; int modbus_data_bits; const char *modbus_parity; int modbus_stop_bits; config_init(&cfg); find_mac(mac_address); if (!config_read_file(&cfg, configfile)) { fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg)); config_destroy(&cfg); fprintf(stderr, "Unable to find configfile.\n"); return -1; } if (!(config_lookup_string(&cfg, "modbus.device", &modbus_device_address) && config_lookup_int(&cfg, "modbus.baud", &modbus_baud_rate) && config_lookup_int(&cfg, "modbus.data_bits", &modbus_data_bits) && config_lookup_string(&cfg, "modbus.parity", &modbus_parity) && config_lookup_int(&cfg, "modbus.stop_bits", &modbus_stop_bits))) { fprintf(stderr, "Incomplete modbus configuration. Check configuration file.\n"); return -1; } if (DEBUG) { printf("%s %s %d %c %d %d\n", mac_address, modbus_device_address, modbus_baud_rate, modbus_parity[0], modbus_data_bits, modbus_stop_bits); } modbus_t *ctx; uint16_t tab_reg[64]; int rc; int i; signal(SIGALRM, minute_check); alarm(60); for (;;) { select(0, NULL, NULL, NULL, NULL); time_t t = time(NULL); time_t unixtime_min = (((int) t) / 60 * 60); //int unixtime = (int) t; //printf("%d\n", unixtime); config_setting_t *registers; registers = config_lookup(&cfg, "register"); unsigned int num_registers = config_setting_length(registers); int i; for (i = 0; i < num_registers; ++i) { config_setting_t *register_element = config_setting_get_elem( registers, i); int slaveid; config_setting_lookup_int(register_element, "slaveid", &slaveid); int intervalvalue; config_setting_lookup_int(register_element, "intervalvalue", &intervalvalue); //printf("%d", intervalvalue); int startaddress; config_setting_lookup_int(register_element, "startaddress", &startaddress); int numregisters; config_setting_lookup_int(register_element, "numregisters", &numregisters); const char *intervalunit; config_setting_lookup_string(register_element, "intervalunit", &intervalunit); //printf("%c", intervalunit[0]); int intervalduration; if (intervalunit[0] == 'h') intervalduration = intervalvalue * 3600; else intervalduration = intervalvalue * 60; if (unixtime_min % intervalduration == 0) { //printf("specified minute. %d %d\n", unixtime_min, // intervalduration); ctx = modbus_new_rtu(modbus_device_address, modbus_baud_rate, modbus_parity[0], modbus_data_bits, modbus_stop_bits); modbus_set_slave(ctx, slaveid); modbus_set_debug(ctx, DEBUG); if (ctx == NULL) { fprintf(stderr, "Unable to create libmodbus object.\n"); //return -1; } if (modbus_connect(ctx) == -1) { fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); modbus_free(ctx); //return -1; } rc = modbus_read_input_registers(ctx, startaddress, numregisters, tab_reg); if (rc == -1) { fprintf(stderr, "ERROR: %s\n", modbus_strerror(errno)); //return -1; rc = modbus_read_input_registers(ctx, startaddress, numregisters, tab_reg); } //_YYYY_MM_DD_HH_MM_SS.log time_t unixtime_day = ((((int) t) / 86400 * 86400) + 86400); struct tm midnight = *localtime(&unixtime_day); char filename[50]; sprintf(filename, "%s_%04i_%02i_%02i_%02i_%02i_%02i.log", mac_address, midnight.tm_year + 1900, midnight.tm_mon + 1, midnight.tm_mday, midnight.tm_hour, midnight.tm_min, midnight.tm_sec); //printf("%s\n",filename); FILE *fp = fopen(filename, "r"); if (fp) { fclose(fp); } else { // file doesn't exist. create it. FILE *fp = fopen(filename, "w"); fprintf( fp, "IntervalID|UTCDate|UTCTime|LOCALDate|LOCALTime|SensorID|RegisterID|Reading\n"); fclose(fp); } FILE *filehandle = fopen(filename, "a+"); uint16_t registervalue = 0; int p; for (p = 0; p < numregisters; p = p + 2) { registervalue += tab_reg[i] + tab_reg[i + 1]; } struct tm utc = *gmtime(&unixtime_min); struct tm lc = *localtime(&unixtime_min); fprintf( filehandle, "1|%04i%02i%02i|%02i%02i%02i|%04i%02i%02i|%02i%02i%02i|%i|%i|%i\n", utc.tm_year + 1900, utc.tm_mon + 1, utc.tm_mday, utc.tm_hour, utc.tm_min, utc.tm_sec, lc.tm_year + 1900, lc.tm_mon + 1, lc.tm_mday, lc.tm_hour, lc.tm_min, lc.tm_sec, slaveid, startaddress, registervalue); fclose(filehandle); modbus_close(ctx); modbus_free(ctx); sleep(1); //return 0; } //printf("%d ", slaveid); } //printf("%d\n", unixtime_min); } }