/*lcap2019 - 9/30/2019 - CJC - Capture mMII data on open systems like RPi (from Dan's MCAP), support mMI input: ttyS0 or ctcap.txt, output: ctcap2.txt, appended line to mmdb1.txt MicroMeter data acquisition software for UNIX (POSIX) by Dan D'Andrea (c) 1999 MicroMeter corporation*/ #include #include #include #include #include #include #include #include #include /* Define device to use and speed */ #define BAUDRATE B300 #define MODEMDEVICE "/dev/ttyAMA0" //ttyS0 ubuntu ttyAMA0 RPi /* This is POSIX source */ #define _POSIX_SOURCE 1 // As if C was too bloated, itoa() was omitted from ANSI C. const char *itoa(int n, char *string, int m) { sprintf(string, "%d", n); return string; } /* Begin main program */ int main(int argc, char *argv[]) { char vstr1[85] = "microMETER lcap2019.c v2.3 usage: ./a.out xxxx or init or mm01 \n\r"; printf("%s",vstr1); /* Setup variables */ int fd, danread, logfile, danwrite, g, h, i, commas, cti,debug=0,fp1; int bbi,ddi,cci,eei,ffi,ggi,hhi,rec2i,mmdb1; int type=1; //mMI or mMII char QS[2]; char qt ='"';//QS[0]=qt;<--put in main()//(char) 34; char dan; char *nine; nine="9"; char ct[10], bb[10], cc[10], dd[10],ee[10],ff[10],gg[10],hh[10]; char rec2[80],rec3[80],rec4[80],rec5[800]; char sg01[50],sg02[50],sg03[50],sg04[50],sg05[50],sg06[50],sg07[50],sg08[50]; char sg09[50],sg10[50],sg11[50],sg12[50],sg13[50],sg14[50],sg15[50],sg16[50]; struct termios oldtio,newtio; char *zero; zero="0"; char *cma; cma=","; char *nul; nul=""; char *temp1; temp1=" "; struct tm *Sys_T = NULL; int Sec,Min,Hour,Day,Month,Year; char temp2[40], temp3[40], hd1[5],hd2[9],hd3[7]; char fil1[40],fil2[40];//allow extra byte for null terminator QS[0]=qt; //Establish header data and subdirectory which comes in as 1st argv, s/b 4 bytes strcpy(hd1,argv[1]); //printf(" hd1 = %s\n", hd1); //init function - create support files if(strcmp(hd1,"init")==0)goto init1; // (the one and only goto) if(strlen(hd1)!=4) { strcpy(hd1,"mm01"); printf("Fixed hd1 = %s\n", hd1); }; if(strlen(hd1)!=4) { printf("%s\n Invalid subfolder - s/b like mm01. "); exit(EXIT_FAILURE); }; strcpy(fil1,hd1); strcat(fil1,"/ctcap2.txt");//legacy cap file (output) strcpy(fil2,hd1); strcat(fil2,"/mmdb1.txt");//database //datetime time_t Tval = 0; Tval = time(NULL); Sys_T = localtime(&Tval); Sec=Sys_T->tm_sec; Min=Sys_T->tm_min; Hour=Sys_T->tm_hour; Day=Sys_T->tm_mday; Month=Sys_T->tm_mon+1; Year=1900 + Sys_T->tm_year; itoa(Year,temp2,10); strcpy(hd2,temp2); itoa(Month,temp2,10);//prepend 0's if needed if (strlen(temp2) < 2) { strcpy(rec3,zero); strcat(rec3,temp2); strcpy(temp2,rec3); }; strcat(hd2,temp2); itoa(Day,temp2,10); if (strlen(temp2) < 2) { strcpy(rec3,zero); strcat(rec3,temp2); strcpy(temp2,rec3); }; strcat(hd2,temp2); itoa(Hour,temp3,10); if (strlen(temp3) < 2) { strcpy(rec3,zero); strcat(rec3,temp3); strcpy(temp3,rec3); }; strcpy(hd3,temp3); itoa(Min,temp3,10); if (strlen(temp3) < 2) { strcpy(rec3,zero); strcat(rec3,temp3); strcpy(temp3,rec3); }; strcat(hd3,temp3); itoa(Sec,temp3,10); if (strlen(temp3) < 2) { strcpy(rec3,zero); strcat(rec3,temp3); strcpy(temp3,rec3); }; strcat(hd3,temp3); printf(" %s%s%s%s",hd1,hd2,hd3, "\n\r"); //--------------------------------------------------------- main process /* Open up the device the MicroMeter is attached to */ fd = open(MODEMDEVICE, O_RDONLY | O_NOCTTY | O_NONBLOCK); if (fd <0) { perror(MODEMDEVICE); exit(EXIT_FAILURE); } /* save current serial port settings */ tcgetattr(fd,&oldtio); /* clear struct for new port settings */ bzero(&newtio, sizeof(newtio)); newtio.c_cflag = BAUDRATE | CS8 | CREAD | CLOCAL; newtio.c_iflag = IGNPAR | ICRNL;/*Raw output.*/ newtio.c_oflag = 0; newtio.c_lflag = ICANON; /*now clean the modem line and activate the settings for the port*/ tcflush(fd, TCIFLUSH); tcsetattr(fd,TCSANOW,&newtio); /* delete old logfile */ strcpy(temp2,"rm -f "); strcat(temp2,fil1); system(temp2); /* open logfile for output */ logfile = open(fil1,O_RDWR | O_CREAT,0); /* Start main loop */ h=0; while (h < 17) { h++; startover: /* Clear out arrays */ for (g = 0; g <= 10; g++) ct[g] = 0; for (g = 0; g <= 10; g++) bb[g] = 0; for (g = 0; g <= 10; g++) cc[g] = 0; for (g = 0; g <= 10; g++) dd[g] = 0; for (g = 0; g <= 10; g++) ee[g] = 0; for (g = 0; g <= 10; g++) ff[g] = 0; for (g = 0; g <= 10; g++) gg[g] = 0; for (g = 0; g <= 10; g++) hh[g] = 0; for (g = 0; g <= 80; g++) rec2[g] = 0; /* initialize variables */ i = 0; commas = 0; cti = 0; bbi = 0; cci = 0; ddi = 0; eei = 0; ffi = 0; ggi = 0; hhi = 0; rec2i=0; /* read data from MicroMeter */ //printf("commas- %i\n\r",commas); while(1) { danread = read(fd,&dan,1); if (danread == 1) { if (dan == '\n') break; if (dan == ',') { commas++; rec2[rec2i] = dan; rec2i++; } else { //printf("commas %i\n\r",commas); if (commas > 3 && type == 1) { type=2; printf("\n\r type 2 \n\r"); } if (commas == 0) { ct[cti] = dan; // 8 values come in from type 2 processor cti++; } if (commas == 1) { bb[bbi] = dan; // 3 long names shortened bbi++; } if (commas == 2) { cc[cci] = dan; cci++; } if (commas == 3) { dd[ddi] = dan; // as if it is Type 1 ddi++; } if (type == 2) { if (commas == 4) { ee[eei] = dan; // 4 new names are short // it must be Type 2 eei++; } if (commas == 5) { ff[ffi] = dan; ffi++; } if (commas == 6) { gg[ggi] = dan; ggi++; } if (commas == 7) { hh[hhi] = dan; hhi++; } } if (type == 1) { if (commas == 1) { ee[eei] = dan; // 4 new names are short // it must be Type 2 eei++; } if (commas == 2) { ff[ffi] = dan; ffi++; } if (commas == 3) { gg[ggi] = dan; ggi++; } } if (commas < 20) { rec2[rec2i] = dan; //simple buffer, un-parsed w commas rec2i++; } } } } if (commas == 0) goto startover;//loop tag above ct[cti+1] = '\0'; bb[bbi+1] = '\0'; cc[cci+1] = '\0'; dd[ddi+1] = '\0'; ee[eei+1] = '\0'; ff[ffi+1] = '\0'; gg[ggi+1] = '\0'; hh[hhi+1] = '\0'; rec2[rec2i+1] = '\0'; if (h == 1) { printf("sync \n\r"); };//always toss first line, might not be complete if (h > 1 && h < 18) { printf("__%s\n\r",rec2);//show 16 raw lines being captured write(logfile,&rec2,strlen(rec2)); write(logfile,"\n\r",1);//put out legacy file //put leading zeros on all parsed values to make uniform lengths of 2 3 5 5 3 5 5 5 if (strlen(ct) < 2) { strcpy(rec3,zero); strcat(rec3,ct); strcpy(ct,rec3); }; if (strlen(bb) < 3) { strcpy(rec3,zero); strcat(rec3,bb); strcpy(bb,rec3); }; if (strlen(bb) < 3) { strcpy(rec3,zero); strcat(rec3,bb); strcpy(bb,rec3); }; if (strlen(cc) < 5) { strcpy(rec3,zero); strcat(rec3,cc); strcpy(cc,rec3); }; if (strlen(cc) < 5) { strcpy(rec3,zero); strcat(rec3,cc); strcpy(cc,rec3); }; if (strlen(cc) < 5) { strcpy(rec3,zero); strcat(rec3,cc); strcpy(cc,rec3); }; if (strlen(cc) < 5) { strcpy(rec3,zero); strcat(rec3,cc); strcpy(cc,rec3); }; if (strlen(dd) < 5) { strcpy(rec3,zero); strcat(rec3,dd); strcpy(dd,rec3); }; if (strlen(dd) < 5) { strcpy(rec3,zero); strcat(rec3,dd); strcpy(dd,rec3); }; if (strlen(dd) < 5) { strcpy(rec3,zero); strcat(rec3,dd); strcpy(dd,rec3); }; if (strlen(dd) < 5) { strcpy(rec3,zero); strcat(rec3,dd); strcpy(dd,rec3); }; if (strlen(ee) < 3) { strcpy(rec3,zero); strcat(rec3,ee); strcpy(ee,rec3); }; if (strlen(ee) < 3) { strcpy(rec3,zero); strcat(rec3,ee); strcpy(ee,rec3); }; if (strlen(ff) < 5) { strcpy(rec3,zero); strcat(rec3,ff); strcpy(ff,rec3); }; if (strlen(ff) < 5) { strcpy(rec3,zero); strcat(rec3,ff); strcpy(ff,rec3); }; if (strlen(ff) < 5) { strcpy(rec3,zero); strcat(rec3,ff); strcpy(ff,rec3); }; if (strlen(ff) < 5) { strcpy(rec3,zero); strcat(rec3,ff); strcpy(ff,rec3); }; if (strlen(gg) < 5) { strcpy(rec3,zero); strcat(rec3,gg); strcpy(gg,rec3); }; if (strlen(gg) < 5) { strcpy(rec3,zero); strcat(rec3,gg); strcpy(gg,rec3); }; if (strlen(gg) < 5) { strcpy(rec3,zero); strcat(rec3,gg); strcpy(gg,rec3); }; if (strlen(gg) < 5) { strcpy(rec3,zero); strcat(rec3,gg); strcpy(gg,rec3); }; if (strlen(hh) < 5) { strcpy(rec3,nine); strcat(rec3,hh); strcpy(hh,rec3); }; if (strlen(hh) < 5) { strcpy(rec3,nine); strcat(rec3,hh); strcpy(hh,rec3); }; if (strlen(hh) < 5) { strcpy(rec3,nine); strcat(rec3,hh); strcpy(hh,rec3); }; if (strlen(hh) < 5) { strcpy(rec3,nine); strcat(rec3,hh); strcpy(hh,rec3); }; if (strlen(hh) < 5) { strcpy(rec3,nine); strcat(rec3,hh); strcpy(hh,rec3); }; // hh will always be 10xxx, cma="," each ct segment starts w comma and ends w/o strcpy(rec4,cma);//build 41-char segment strcat(rec4,ct); strcat(rec4,cma); strcat(rec4,bb); strcat(rec4,cma); strcat(rec4,cc); strcat(rec4,cma); strcat(rec4,dd); strcat(rec4,cma); strcat(rec4,ee); strcat(rec4,cma); strcat(rec4,ff); strcat(rec4,cma); strcat(rec4,gg); strcat(rec4,cma); strcat(rec4,hh); //....+....1....+....2....+....3....+....4....+....5....+....6....+....7 //,01,010,38979,00028,010,38979,00028,10000 if(strcmp(ct,"01")==0) { strcpy(sg01,rec4); }; if(strcmp(ct,"02")==0) { strcpy(sg02,rec4); }; if(strcmp(ct,"03")==0) { strcpy(sg03,rec4); }; if(strcmp(ct,"04")==0) { strcpy(sg04,rec4); }; if(strcmp(ct,"05")==0) { strcpy(sg05,rec4); }; if(strcmp(ct,"06")==0) { strcpy(sg06,rec4); }; if(strcmp(ct,"07")==0) { strcpy(sg07,rec4); }; if(strcmp(ct,"08")==0) { strcpy(sg08,rec4); }; if(strcmp(ct,"09")==0) { strcpy(sg09,rec4); }; if(strcmp(ct,"10")==0) { strcpy(sg10,rec4); }; if(strcmp(ct,"11")==0) { strcpy(sg11,rec4); }; if(strcmp(ct,"12")==0) { strcpy(sg12,rec4); }; if(strcmp(ct,"13")==0) { strcpy(sg13,rec4); }; if(strcmp(ct,"14")==0) { strcpy(sg14,rec4); }; if(strcmp(ct,"15")==0) { strcpy(sg15,rec4); }; if(strcmp(ct,"16")==0) { strcpy(sg16,rec4); }; //printf("%s\n\r",rec4); strcpy(rec4,nul); } } close(logfile); /* restore the old port settings */ tcsetattr(fd,TCSANOW,&oldtio); strcpy(rec5,nul); strcat(rec5,hd1); strcat(rec5,hd2); strcat(rec5,hd3);//1st 18 bytes strcat(rec5,sg01); strcat(rec5,sg02); strcat(rec5,sg03); strcat(rec5,sg04); strcat(rec5,sg05); strcat(rec5,sg06); strcat(rec5,sg07); strcat(rec5,sg08); strcat(rec5,sg09); strcat(rec5,sg10); strcat(rec5,sg11); strcat(rec5,sg12); strcat(rec5,sg13); strcat(rec5,sg14); strcat(rec5,sg15); strcat(rec5,sg16);//674 bytes //mm0120020909131542,01,010,38979,00028,010,38979,00028,10000, 15 more groups mMII //....+....1....+....2....+....3....+....4....+....5....+....6....+....7 /* open mm.db1 for append */ mmdb1 = open(fil2,O_RDWR | O_APPEND | O_CREAT,0); write(mmdb1,&rec5,strlen(rec5)); write(mmdb1,"\n\r",1); printf("%s\n\r ",rec5); close(mmdb1); strcpy(temp2,"chmod 666 "); strcat(temp2,fil1); system(temp2); strcpy(temp2,"chmod 666 "); strcat(temp2,fil2); system(temp2); exit(EXIT_SUCCESS); //----------------------------------------------------------- special case to create files init1: printf("init function\n\r"); system("mkdir test"); /* microMETER Corp. Energy usage charges due and payable for the period ending. Taxes and customer charges have been added proportionately. Thank you for your prompt payment. Customer Billing Period Usage Amount Due Rate: Non-demand, Non-TOU - Customer chg incl. @ xxxx cts/kwh */ strcpy(temp3,"test/micro.txt"); fp1 = open(temp3,O_RDWR | O_CREAT,0); //....+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8....+....9....+ strcpy(rec5," your name here "); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); strcpy(rec5," "); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); strcpy(rec5," Energy usage charges due and payable for the period ending. "); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); strcpy(rec5," Taxes and customer charges have been added proportionately. "); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); strcpy(rec5," Thank you for your prompt payment. "); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); strcpy(rec5," Customer Billing Period Usage Amount Due"); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); strcpy(rec5," Rate: Non-demand, Non-TOU - Customer chg incl. @ xxxx cts/kwh "); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); close(fp1); strcpy(temp2,"chmod 666 "); strcat(temp2,temp3); system(temp2); /* 12.75 2516.447 16.95 1 0 1 2 3 4 5 6 7 7 7 0 0 */ strcpy(temp3,"test/microdat.txt"); fp1 = open(temp3,O_RDWR | O_CREAT,0); //....+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8....+....9....+ strcpy(rec5," 12.75 "); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); strcpy(rec5," 2516.447 "); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); strcpy(rec5," 16.95 "); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); strcpy(rec5," 1 "); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); strcpy(rec5," 0 1 2 3 "); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); strcpy(rec5," 4 5 6 7 "); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); strcpy(rec5," 7 7 0 0 "); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); close(fp1); strcpy(temp2,"chmod 666 "); strcat(temp2,temp3); system(temp2); /* 1 - "0020,1.00,120,000,999 . 2 - "0020,1.00,120,000,999 . 3 - "0020,1.00,120,000,999 . 4 - "0020,1.00,120,000,003 . 5 - "0020,1.00,120,000,999 . 6 - "0020,1.00,120,000,999 . 7 - "0020,1.00,120,000,999 . 8 - "0020,1.00,120,000,999 . 9 - "0020,1.00,120,000,999 . 10 - "0020,1.00,120,000,999 . 11 - "0020,1.00,120,000,999 . 12 - "0020,1.00,120,000,999 . 13 - "0020,1.00,120,000,999 . 14 - "0020,1.00,120,000,999 . 15 - "0020,1.00,120,000,999 . 16 - "0020,1.00,120,000,999 . */ strcpy(temp3,"test/ctdat.txt"); fp1 = open(temp3,O_RDWR | O_CREAT,0); //....+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8....+....9....+ strcpy(rec5," 1 - "); strcat(rec5,QS); strcat(rec5,"0020,1.00,120,000,999 ."); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); strcpy(rec5," 2 - "); strcat(rec5,QS); strcat(rec5,"0020,1.00,120,000,999 ."); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); strcpy(rec5," 3 - "); strcat(rec5,QS); strcat(rec5,"0020,1.00,120,000,999 ."); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); strcpy(rec5," 4 - "); strcat(rec5,QS); strcat(rec5,"0020,1.00,120,000,999 ."); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); strcpy(rec5," 5 - "); strcat(rec5,QS); strcat(rec5,"0020,1.00,120,000,999 ."); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); strcpy(rec5," 6 - "); strcat(rec5,QS); strcat(rec5,"0020,1.00,120,000,999 ."); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); strcpy(rec5," 7 - "); strcat(rec5,QS); strcat(rec5,"0020,1.00,120,000,999 ."); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); strcpy(rec5," 8 - "); strcat(rec5,QS); strcat(rec5,"0020,1.00,120,000,999 ."); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); strcpy(rec5," 9 - "); strcat(rec5,QS); strcat(rec5,"0020,1.00,120,000,999 ."); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); strcpy(rec5," 10 - "); strcat(rec5,QS); strcat(rec5,"0020,1.00,120,000,999 ."); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); strcpy(rec5," 11 - "); strcat(rec5,QS); strcat(rec5,"0020,1.00,120,000,999 ."); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); strcpy(rec5," 12 - "); strcat(rec5,QS); strcat(rec5,"0020,1.00,120,000,999 ."); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); strcpy(rec5," 13 - "); strcat(rec5,QS); strcat(rec5,"0020,1.00,120,000,999 ."); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); strcpy(rec5," 14 - "); strcat(rec5,QS); strcat(rec5,"0020,1.00,120,000,999 ."); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); strcpy(rec5," 15 - "); strcat(rec5,QS); strcat(rec5,"0020,1.00,120,000,999 ."); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); strcpy(rec5," 16 - "); strcat(rec5,QS); strcat(rec5,"0020,1.00,120,000,999 ."); write(fp1,&rec5,strlen(rec5)); write(fp1,"\n\r",1); close(fp1); strcpy(temp2,"chmod 666 "); strcat(temp2,temp3); system(temp2); //end init function } /* EOF */