1 // Copyright (c) 2017, Tobias Mueller tm(at)tm3d.de
2 // All rights reserved.
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the
14 // * All advertising materials mentioning features or use of this
15 // software must display the following acknowledgement: This product
16 // includes software developed by tm3d.de and its contributors.
17 // * Neither the name of tm3d.de nor the names of its contributors may
18 // be used to endorse or promote products derived from this software
19 // without specific prior written permission.
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #include "mySensorDB.h"
40 #include <fcntl.h> /* For O_RDWR */
54 #define RB "\e(0\x6a\e(B" // 188 Right Bottom corner
55 #define RT "\e(0\x6b\e(B" // 187 Right Top corner
56 #define LT "\e(0\x6c\e(B" // 201 Left Top cornet
57 #define LB "\e(0\x6d\e(B" // 200 Left Bottom corner
58 #define MC "\e(0\x6e\e(B" // 206 Midle Cross
59 #define HL "\e(0\x71\e(B" // 205 Horizontal Line
60 #define LC "\e(0\x74\e(B" // 204 Left Cross
61 #define RC "\e(0\x75\e(B" // 185 Right Cross
62 #define BC "\e(0\x76\e(B" // 202 Bottom Cross
63 #define TC "\e(0\x77\e(B" // 203 Top Cross
64 #define VL "\e(0\x78\e(B" // 186 Vertical Line
65 #define SP " " // space string
69 printf("owTools - Programm for reading und controlling 1-Wire Devices from www.tm3d.de\n\n");
70 printf("run: owTools -a [COMn|USBn|GPIOn] [options]\n\n");
71 printf(" COMn -> Adapter DS9097 and compatible (e.g. LinkUSB)\n");
72 printf(" n=1 -> Windows COM1 -> Linux /dev/ttyS1\n");
73 printf(" USBn -> Adapter DS2490/DS9490 \n");
74 printf(" n=1 -> first USB-Adapter \n");
75 printf(" GPIOn -> port of Raspberry PI (port Name not Pin number)\n\n");
77 printf(" -i interactive mode\n");
78 printf(" select a device and get information about it\n");
79 printf(" -c read and print all continuous\n");
80 printf(" -p time in sec between readings\n");
81 printf(" -d [config file] put all Data in mysql Database descripted in Config file\n");
82 printf(" Config file: \n");
83 printf(" [server]\n");
84 printf(" [port] -> 3306\n");
86 printf(" [password]\n");
87 printf(" [database]\n");
88 printf(" [prefix] -> a prefix of all tables \n\n");
89 printf(" -r Search everytime for new Devices\n");
90 printf(" -f hexfile Flash new\n");
91 printf(" -n change id \n");
92 printf(" -g get from server\n");
93 printf(" -w [1|2] show Warnings (1) or all Infos (2)\n");
106 //length of shown chars of an UTF8 string ... sometimes not the same as byte count
107 std::size_t utf8_length(std::string const &s) {
109 std::string::const_iterator begin = s.begin(), end = s.end();
110 while (begin != end) {
111 unsigned char c = *begin;
113 if ((c & 0x80) == 0) n = 1;
114 else if ((c & 0xE0) == 0xC0) n = 2;
115 else if ((c & 0xF0) == 0xE0) n = 3;
116 else if ((c & 0xF8) == 0xF0) n = 4;
125 std::vector<arg_t> comlist;
127 std::string getArg(std::string flag) {
128 for(arg_t a:comlist) {
129 if (a.flag==flag) return a.arg;
136 int getArgi(std::string flag) {
137 return atoi(getArg(flag).c_str());
142 mySensorDB *sdb=NULL;
145 snum_t getArgsnum(std::string flag) {
151 int findCPU(std::string cpu) {
152 std::ifstream fileInput;
154 fileInput.open("/proc/cpuinfo");
155 if(fileInput.is_open()) {
156 for(unsigned int curLine = 0; getline(fileInput, line); curLine++) {
157 if (line.find(cpu) != std::string::npos) {
171 owInterface *owi= NULL;
174 if (getArg("w")=="2")
175 owi->log->setLogLevel(0);
176 else if (getArg("w")=="2") owi->log->setLogLevel(0);
177 else owi->log->setLogLevel(OWLOG_ERROR);
182 void continuous(std::vector<owDevice*> *devices,int intervall,int headline,int searchrom) {
188 if (owi->isDevicesChanged()||(first==1)) {
192 for (owDevice* dev :*devices) {
193 if (dev->configstate!=OWDCS_NONE) {
194 for (size_t i=0;i<4;i++) {
195 if (dev->config->getPropertyID(i)!=0)
196 printf("\033[1;34m%02X.%02X%02X\033[0m\t",dev->getNum().byte[7],dev->getNum().byte[1],dev->getNum().byte[0]);
201 for (owDevice* dev :*devices) {
202 if (dev->configstate!=OWDCS_NONE) {
203 for (size_t i=0;i<4;i++) {
204 if (dev->config->getPropertyID(i)!=0)
205 printf("\033[0;36m%s\033[0m\t",dev->config->getQuantity(i).substr(0,7).c_str());
210 for (owDevice* dev :*devices) {
211 if (dev->configstate!=OWDCS_NONE) {
212 for (size_t i=0;i<4;i++) {
213 if (dev->config->getPropertyID(i)!=0)
214 printf("\033[3;34m[%s] \033[0m\t",dev->config->getUnit(i).c_str());
223 //owi->log->setLogLevel(0);
224 for (owDevice* dev : *devices) {
225 sdb->createDeviceTable(dev);
233 struct tm tm = *localtime(&t);
234 printf("%d-%02d-%02d %02d:%02d:%02d\t", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
235 for (owDevice* dev :*devices) {
236 for(int k=0;k<owi->maxrepeat;k++){
238 if (owi->log->last()<OWLOG_ERROR) break;
241 if (owi->log->last()<OWLOG_ERROR) {
242 if (dev->configstate!=OWDCS_NONE) {
243 for (size_t i=0;i<4;i++) {
244 if (dev->config->getPropertyID(i)!=0) {
245 if (dev->values[i]<10)
246 printf("%0.4f \t",dev->values[i]);
247 else if (dev->values[i]<100)
248 printf("%0.3f \t",dev->values[i]);
249 else if (dev->values[i]<1000)
250 printf("%0.2f \t",dev->values[i]);
252 printf("%0.1f \t",dev->values[i]);
258 sdb->insertValues(dev);
261 owi->log->setLogLevel(OWLOG_INFO);
262 owi->log->set(OWLOG_ERROR,"Too many errors, mybee conection is dead.");
269 while (((int)time(NULL))<(st+intervall)) sleep(1);
273 void device_menu(owDevice* d) {
274 for(int i=0;i<70;i++) printf(HL);printf("\n");
275 printf("Selected Device: ");
276 snum_t snum=d->getNum();
277 printf("\033[1;34m%016llX\033[0m",(unsigned long long)snum.num);
279 printf("Chip Info: ");
280 std::vector<std::string> info=d->getFamilyInfo();
281 for (std::string s : info) printf(" %s",s.c_str());
283 printf("Values info: ");
284 int tm3d=d->readConfig();
285 for (size_t i=0;i<4;i++) {
286 printf("%s in %s",d->config->getQuantity(i).c_str(),d->config->getUnit(i).c_str());
287 if (i<4) printf("; ");
289 if (tm3d) printf(" (tm3d.de)"); else printf(" (default)");
292 for (size_t i=0;i<d->values.size();i++) {
293 printf("\033[1;33m%0.4f %s\033[0m ",d->values[i],d->config->getUnit(i).c_str());
296 for(int i=0;i<70;i++) printf(HL);printf("\n");
298 printf("1) Run continuous\n");
301 printf("Select an option: ");std::getline (std::cin,inp);
302 int dnr=atoi(inp.c_str());
305 std::vector<owDevice*> v;
307 continuous(&v,1,1,0);
309 // if (dnr<=i) break;
310 // printf("\033[4;33mSelect a number between 0 and %i\033[0m\n",i);
319 for (owDevice* dev :owi->devices) {
321 snum_t snum=dev->getNum();
323 printf("\033[1;34m%016llX\033[0m",(unsigned long long)snum.num);
326 for (int j=0;j<4;j++) printf("%s ",dev->config->getQuantity(j).c_str());
329 printf("0) Exit Programm\n");
333 printf("Select device with number: ");std::getline (std::cin,inp);
334 dnr=atoi(inp.c_str());
335 if (dnr<=0) return 0;
337 printf("\033[4;33mSelect a number between 0 and %i\033[0m\n",i);
343 int questionYesNo(std::string text) {
345 printf("%s [Y/n] ",text.c_str());std::getline (std::cin,inp);
346 if (inp=="Y") return 1; else return 0;
350 void interactive(owInterface *owi) {
352 int i=selectDevice();
354 device_menu(owi->devices[i-1]);
358 int main(int argc, char *argv[]) {
361 //printf("Kommando: %s:\n", argv[0]);
363 if (**++argv != '-') {
364 //printf(" Arg. = %s\n", *argv);
365 if (comlist.empty()) {
368 comlist.push_back(a);
370 if ((*(comlist.end()-1)).arg!="1") {
373 comlist.push_back(a);
375 (*(comlist.end()-1)).arg=*argv;
379 for( i=1; (*argv)[i] != '\0'; i++) {
380 //printf(" Flag = (%c)\n", (*argv)[i]);
383 comlist.push_back(a);
388 //for(arg_t a:comlist) printf("%s->%s\n",a.flag.c_str(),a.arg.c_str());
389 if (getArg("h")=="1") {
393 std::string adapter=getArg("a");
394 if (adapter.empty()) {
398 std::transform(adapter.begin(), adapter.end(),adapter.begin(), ::toupper);
402 if(adapter.find("COM")!=std::string::npos) {
403 owi=new owCOMInterface();
404 int port=atoi(adapter.substr(adapter.find("COM")+3).c_str());
405 printf("Open /dev/ttyS%i\n",port);
406 owi->InitAdapter(port);
408 if(adapter.find("USB")!=std::string::npos) {
409 owi=new owUSBInterface();
410 int port=atoi(adapter.substr(adapter.find("USB")+3).c_str());
411 printf("Open the %i. USB Adapter\n",port);
413 if ((err=owi->InitAdapter(port))<0) {
414 if (err==-1) printf("No Adapter found!\n On Linux, try: sudo owTools....\n On Windows: Install libusb0 driver\n");
415 if (err==-2) printf("Maybe Adapter is used ... (try sudo)\nOn Linux: If the kernel modul is loaded type: sudo rmmod ds2490\n");
419 if(adapter.find("GPIO")!=std::string::npos) {
420 if (findCPU("BCM2708")) {
421 printf("\033[1;33mRaspberry Pi 1 is dedected. 1-wire on the GPIO port can have many errors in the transfer.\033[0m\n");
422 owi=new owPiGPioInterface();
423 int port=atoi(adapter.substr(adapter.find("GPIO")+4).c_str());
424 printf("Open GPIO %i\n",port);
425 } else if (findCPU("BCM2709")) {
426 owi=new owPiGPioInterface();
427 int port=atoi(adapter.substr(adapter.find("GPIO")+4).c_str());
428 printf("Open GPIO %i\n",port);
429 owi->InitAdapter(port);
431 printf("\033[1;31mGPIO works with Raspberry PI only \033[0m\n");
441 if (getArg("i")=="1") {
444 if (getArg("c")=="1") {
445 int reload=(getArg("r")=="1");
448 //owi->log->setLogLevel(3);
451 if ((s=getArg("p")) !="") {
452 pause=atoi(s.c_str());
454 if ((s=getArg("d")) !="") {
456 printf("Use Database\n");
457 sdb=new mySensorDB(s,owi->log);
458 if (sdb->log->last()>OWLOG_WARNING) {
462 if (sdb->log->last()>OWLOG_WARNING) {
465 sdb->createSensorTable();
466 if (sdb->log->last()>OWLOG_WARNING) {
473 continuous(&(owi->devices),pause,1,reload);
475 if ((s=getArg("f"))!="") {
476 printf("Flash %s in selected Device\n",s.c_str());
477 int sel=selectDevice();
479 int resetid=questionYesNo("Would you reset to default ID? (This is necessary if another device is used!)");
480 owi->log->setLogLevel(OWLOG_INFO);
481 owi->flashHEXFile(s,owi->device_nums[sel-1],resetid,1);
485 for (owDevice* dev :owi->devices) {
486 snum_t snum=dev->getNum();
487 printf("\033[1;34m%016llX\033[0m",(unsigned long long)snum.num);
491 printf("%i Devices found\n",(int)owi->devices.size());
495 if ((s=getArg("n"))!="") {
496 printf("Change id of selected Device\n");
497 int sel=selectDevice();
501 snum_t snum=owi->devices[sel]->getNum();
502 if ((getArg("g"))=="1") {
503 printf("get ID from Server\n");
505 sprintf(s,"wget -q http://www.tm3d.de/shop99/owid.php?fam=%02X -O id.txt",snum.byte[0]);
507 if ((err=system(s))==0) {
510 std::stringstream str;
516 while(fs.peek() != EOF) {
517 char c= (char) fs.get();
521 if ((c==',')|(c=='}')) {
522 isnum.byte[i]=strtol(s, NULL, 16);
523 //printf("%x\n",strtol(s, NULL, 16));
539 } else (printf("ERROR %i\n",err));
546 printf("\033[1;34m%016llX\033[0m",(unsigned long long)snum.num);
550 owi->devices[sel]->changeID(snum);
554 for (owDevice* dev :owi->devices) {
555 snum_t snum=dev->getNum();
556 printf("\033[1;34m%016llX\033[0m",(unsigned long long)snum.num);
560 printf("%i Devices found\n",(int)owi->devices.size());
564 for (owDevice* dev :owi->devices) {
565 printf("_______________________________________________________________________\n");
566 snum_t snum=dev->getNum();
567 printf("\033[1;34m%016llX\033[0m ",(unsigned long long)snum.num);
568 switch (dev->configstate) {
569 case OWDCS_16:printf("old Configcode from www.tm3d.de");break;
570 case OWDCS_24:printf("Configcode from www.tm3d.de");break;
571 case OWDCS_DEFAULT:printf("Default Configcode set by this Software");break;
572 case OWDCS_NONE:printf("No Configcode");break;
576 printf(" %s",dev->getFamilyInfo()[i].c_str());
578 if (dev->configstate!=OWDCS_NONE) {
579 std::vector<std::vector<std::string>> ia;
580 std::vector<size_t> maxcol;
582 for(int i=0;i<4;i++) {
583 std::vector<std::string> colm;
585 colm.push_back(dev->config->getSensorChip(i));
586 if (max<utf8_length(colm[0])) max=utf8_length(colm[0]);
587 colm.push_back(dev->config->getQuantity(i));
588 if (max<utf8_length(colm[1])) max=utf8_length(colm[1]);
589 colm.push_back(dev->config->getUnit(i));
590 if (max<utf8_length(colm[2])) max=utf8_length(colm[2]);
591 if (dev->config->getPropertyID(i)==0) {
595 sprintf(hs,"%0.3f",dev->values[i]);
598 if (max<utf8_length(colm[3])) max=utf8_length(colm[3]);
600 maxcol.push_back(max);
602 std::string space=" ";
603 for(int i=0;i<4;i++) {
604 for(int j=0;j<4;j++) {
605 printf("%s%s",ia[j][i].c_str(),space.substr(0,maxcol[j]-utf8_length(ia[j][i])+2).c_str());
611 printf("%i Devices found\n",(int)owi->devices.size());