Works now with Windows Visual Studio C++ too
[owTools.git] / src / main.cpp
1 // Copyright (c) 2017, Tobias Mueller tm(at)tm3d.de
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
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
13 //    distribution.
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.
20 //
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.
32
33 #include "owTools.h"
34
35 #ifdef LINUX
36 #include <mysql.h>
37 #include "mySensorDB.h"
38 #include <sys/mman.h>
39 #include <unistd.h>
40 #include <pthread.h>
41 #include <sched.h>
42 #endif
43
44 #ifdef WIN
45 #include "Windows.h"
46 #include "time.h"
47 #endif
48
49 #include <stdio.h>
50 #include <stdlib.h>
51 #include <stdint.h>
52 #include <fcntl.h>    /* For O_RDWR */
53 #include <memory.h>
54 #include "hexfile.h"
55 #include <iostream>
56 #include <algorithm>
57 #include <fstream>
58 #include <sstream> 
59
60 #ifdef LINUX
61
62 #define RB "\e(0\x6a\e(B" // 188 Right Bottom corner
63 #define RT "\e(0\x6b\e(B" // 187 Right Top corner
64 #define LT "\e(0\x6c\e(B" // 201 Left Top cornet
65 #define LB "\e(0\x6d\e(B" // 200 Left Bottom corner
66 #define MC "\e(0\x6e\e(B" // 206 Midle Cross
67 #define HL "\e(0\x71\e(B" // 205 Horizontal Line
68 #define LC "\e(0\x74\e(B" // 204 Left Cross
69 #define RC "\e(0\x75\e(B" // 185 Right Cross
70 #define BC "\e(0\x76\e(B" // 202 Bottom Cross
71 #define TC "\e(0\x77\e(B" // 203 Top Cross
72 #define VL "\e(0\x78\e(B" // 186 Vertical Line
73 #define SP " "            // space string
74 #endif
75 #ifdef WIN
76 #define RB " "// 188 Right Bottom corner
77 #define RT  " "// 187 Right Top corner
78 #define LT  " "// 201 Left Top cornet
79 #define LB  " "// 200 Left Bottom corner
80 #define MC " " // 206 Midle Cross
81 #define HL " "// 205 Horizontal Line
82 #define LC  " "// 204 Left Cross
83 #define RC  " "// 185 Right Cross
84 #define BC  " "// 202 Bottom Cross
85 #define TC  " "// 203 Top Cross
86 #define VL  " "// 186 Vertical Line
87 #define SP " "            // space string
88 #endif
89
90 void printhelp() {
91 printf("owTools - Programm for reading und  controlling 1-Wire Devices from www.tm3d.de\n\n");
92 printf("run:  owTools -a [COMn|USBn|GPIOn] [options]\n\n");
93 printf("    COMn -> Adapter DS9097 and compatible (e.g. LinkUSB)\n");
94 printf("         n=1 -> Windows COM1 -> Linux /dev/ttyS1\n");
95 printf("    USBn -> Adapter DS2490/DS9490 \n");
96 printf("         n=1 -> first USB-Adapter \n");
97 printf("    GPIOn -> port of Raspberry PI (port Name not Pin number)\n\n");
98 printf("options:\n");
99 printf("   -i interactive mode\n");
100 printf("          select a device and get information about it\n");
101 printf("   -c read and print all continuous\n");
102 printf("      -p time in sec between readings\n");
103 printf("      -d [config file] put all Data in mysql Database descripted in Config file\n");
104 printf("         Config file: \n");
105 printf("            [server]\n");
106 printf("            [port] -> 3306\n");
107 printf("            [user] \n");
108 printf("            [password]\n");
109 printf("            [database]\n");
110 printf("            [prefix] -> a prefix of all tables \n\n");
111 printf("      -r Search everytime for new Devices\n");
112 printf("   -f hexfile  Flash new\n");
113 printf("   -n change id   \n");
114 printf("      -g get from server\n");
115 printf("   -w [1|2] show Warnings (1) or all Infos (2)\n");
116
117
118
119 }
120
121
122 typedef struct {
123         std::string flag;
124         std::string arg;
125 } arg_t ;
126
127
128 //length of shown chars of an UTF8 string ... sometimes not the same as byte count
129 std::size_t utf8_length(std::string const &s) {
130   std::size_t len = 0;
131   std::string::const_iterator begin = s.begin(), end = s.end();
132   while (begin != end) {
133     unsigned char c = *begin;
134     int n=1;
135     if      ((c & 0x80) == 0)    n = 1;
136     else if ((c & 0xE0) == 0xC0) n = 2;
137     else if ((c & 0xF0) == 0xE0) n = 3;
138     else if ((c & 0xF8) == 0xF0) n = 4;
139     
140     len += 1;
141     begin += n;
142   }
143   return len;
144 }
145
146
147 std::vector<arg_t> comlist;
148
149 std::string getArg(std::string flag) {
150         for(arg_t a:comlist) {
151                 if (a.flag==flag) return a.arg;
152         }
153         return ""; 
154 }
155
156
157
158 int getArgi(std::string flag) {
159         return atoi(getArg(flag).c_str());
160 }
161
162 #ifdef LINUX
163 int database=0;
164 mySensorDB *sdb=NULL;
165 #endif
166 /*
167 snum_t getArgsnum(std::string flag) {
168         snum_t snum;
169         snum.num=0;
170         return snum;
171 }
172 */
173 int findCPU(std::string cpu) {
174         std::ifstream fileInput;
175         std::string line;
176         fileInput.open("/proc/cpuinfo");
177         if(fileInput.is_open()) {       
178                 for(unsigned int curLine = 0; getline(fileInput, line); curLine++) {
179                         if (line.find(cpu) != std::string::npos) {
180                                 fileInput.close();
181                                 return 1;
182                         }
183                 }
184                 fileInput.close();
185                 
186         }
187         return 0;
188 }
189
190
191
192
193 owInterface *owi= NULL;
194
195 void setLogMode() {
196         if (getArg("w")=="2")
197                         owi->log->setLogLevel(0);
198         else if (getArg("w")=="2") owi->log->setLogLevel(0);
199         else owi->log->setLogLevel(OWLOG_ERROR);
200
201 }
202
203
204 void continuous(std::vector<owDevice*> *devices,int intervall,int headline,int searchrom) {
205         int first=1;
206         while (1) {
207                 if (searchrom) {
208                         owi->log->clear();
209                         owi->Find();
210                         if (owi->isDevicesChanged()||(first==1)) {
211                                 first=0;
212                                 if (headline) {
213                                         printf("                     \t");
214                                         for (owDevice* dev :*devices) {
215                                                 if (dev->configstate!=OWDCS_NONE) {
216                                                         for (size_t i=0;i<4;i++) {
217                                                                 if (dev->config->getPropertyID((uint8_t)i)!=0)
218                                                                         printf("\033[1;34m%02X.%02X%02X\033[0m\t",dev->getNum().byte[7],dev->getNum().byte[1],dev->getNum().byte[0]);
219                                                         }
220                                                 }
221                                         }
222                                         printf("\ntime                 \t");
223                                         for (owDevice* dev :*devices) {
224                                                 if (dev->configstate!=OWDCS_NONE) {
225                                                         for (size_t i=0;i<4;i++) {
226                                                                 if (dev->config->getPropertyID((uint8_t)i)!=0)
227                                                                         printf("\033[0;36m%s\033[0m\t",dev->config->getQuantity((uint8_t)i).substr(0,7).c_str());
228                                                         }
229                                                 }
230                                         }
231                                         printf("\n                     \t");
232                                         for (owDevice* dev :*devices) {
233                                                 if (dev->configstate!=OWDCS_NONE) {
234                                                         for (size_t i=0;i<4;i++) {
235                                                                 if (dev->config->getPropertyID((uint8_t)i)!=0) {
236                                                                         size_t l=utf8_length(dev->config->getUnit((uint8_t)i));
237                                                                         std::string ls="           ";
238                                                                         printf("\033[3;34m[%s]%s\033[0m\t",dev->config->getUnit((uint8_t)i).c_str(),ls.substr(0,5-l).c_str());
239                                                                 }
240                                                         }
241                                                 }
242                                         }
243                                         
244                                 }       
245                                 printf("\n");
246 #ifdef LINUX
247                                 if (database) {
248                                         //owi->log->setLogLevel(0);
249                                         for (owDevice* dev : *devices) {
250                                                 sdb->createDeviceTable(dev);
251                                         }
252                                 }
253 #endif
254                         }
255                         
256                 }
257                 time_t t=time(NULL);
258                 int st=(int)t;
259 #ifdef LINUX
260                 struct tm tm = *localtime(&t);
261 #endif
262 #ifdef WIN
263                 struct tm tm;
264                 localtime_s(&tm,&t);
265 #endif
266                 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);
267                 for (owDevice* dev :*devices) {
268                         for(int k=0;k<owi->maxrepeat;k++){
269                                 dev->convertAll();
270                                 if (owi->log->last()<OWLOG_ERROR) break;
271                                 owi->log->clear();
272                         }
273                         if (owi->log->last()<OWLOG_ERROR) {
274                                 if (dev->configstate!=OWDCS_NONE) {
275                                         for (size_t i=0;i<4;i++) {                                      
276                                                 if (dev->config->getPropertyID((int8_t)i)!=0) {
277                                                         if (dev->values[i]<=-10) 
278                                                                 printf("%0.2f \t",dev->values[i]);
279                                                         else if (dev->values[i]<0) 
280                                                                 printf("%0.3f \t",dev->values[i]);
281                                                         else if (dev->values[i]<10) 
282                                                                 printf("%0.4f \t",dev->values[i]);
283                                                         else if (dev->values[i]<100)    
284                                                                 printf("%0.3f \t",dev->values[i]);
285                                                         else if (dev->values[i]<1000)   
286                                                                 printf("%0.2f \t",dev->values[i]);
287                                                         else
288                                                                 printf("%0.1f \t",dev->values[i]);
289                                                         fflush(stdout);
290                                                 }
291                                         }
292                                 }
293 #ifdef LINUX
294                                 if (database) {
295                                         sdb->insertValues(dev);
296                                 }
297 #endif
298                         } else {
299                                 owi->log->setLogLevel(OWLOG_INFO);
300                                 owi->log->set(OWLOG_ERROR,"Too many errors, mybee conection is dead.");
301                                 return;
302                         }
303                         
304                 
305                 }
306                 printf("\n");
307                 while (((int)time(NULL)) < (st + intervall)) {
308 #ifdef LINUX
309                         sleep(1);
310 #endif
311 #ifdef WIN
312                         Sleep(1000);
313 #endif          
314                 }
315         }
316 }
317
318 void device_menu(owDevice* d) {
319         for(int i=0;i<70;i++) printf(HL);printf("\n");
320         printf("Selected Device: ");
321         snum_t snum=d->getNum();
322         printf("\033[1;34m%016llX\033[0m",(unsigned long long)snum.num);
323         printf("  \n");
324         printf("Chip Info: ");
325         std::vector<std::string> info=d->getFamilyInfo();
326         for (std::string s : info) printf(" %s",s.c_str());
327         printf("\n");
328         printf("Values info: ");
329         int tm3d=d->readConfig();
330         for (size_t i=0;i<4;i++) {
331                 printf("%s in %s",d->config->getQuantity((uint8_t)i).c_str(),d->config->getUnit((uint8_t)i).c_str());
332                 if (i<4) printf("; "); 
333         }
334         if (tm3d) printf(" (tm3d.de)"); else printf(" (default)"); 
335         printf("\n");
336         d->convertAll();
337         for (size_t i=0;i<d->values.size();i++) {
338                 printf("\033[1;33m%0.4f %s\033[0m  ",d->values[i],d->config->getUnit((uint8_t)i).c_str());
339         }
340         printf("\n");
341         for(int i=0;i<70;i++) printf(HL);printf("\n");
342         printf("0) Exit\n");
343         printf("1) Run continuous\n");
344         std::string inp;
345         while (1) {
346                 printf("Select an option: ");std::getline (std::cin,inp);
347                 int dnr=atoi(inp.c_str());
348                 if (dnr<=0) return;
349                 if (dnr==1) {
350                         std::vector<owDevice*> v;
351                         v.push_back(d);
352                         continuous(&v,1,1,0);
353                 } 
354 //                      if (dnr<=i) break; 
355         //              printf("\033[4;33mSelect a number between 0 and %i\033[0m\n",i);
356         }
357         
358         
359 }
360
361 int selectDevice() {
362         owi->Find();
363         int i=0;
364         for (owDevice* dev :owi->devices) {
365                 i++;
366                 snum_t snum=dev->getNum();
367                 printf("%i) ",i);
368                 printf("\033[1;34m%016llX\033[0m",(unsigned long long)snum.num);
369
370                 printf("  ");
371                 for (int j=0;j<4;j++) printf("%s ",dev->config->getQuantity(j).c_str());
372                 printf("\n");
373         }
374         printf("0) Exit Programm\n");
375         std::string inp;
376         int dnr=0;
377         while (1) {
378                 printf("Select device with number: ");std::getline (std::cin,inp);
379                 dnr=atoi(inp.c_str());
380                 if (dnr<=0) return 0;
381                 if (dnr<=i) break; 
382                 printf("\033[4;33mSelect a number between 0 and %i\033[0m\n",i);
383         }
384         return dnr;
385
386 }
387
388 int questionYesNo(std::string text) {
389         std::string inp;
390         printf("%s [Y/n] ",text.c_str());std::getline (std::cin,inp);
391         if (inp=="Y") return 1; else return 0;
392         
393 }
394
395 void interactive(owInterface *owi) {
396         while (1) {
397                 int i=selectDevice();
398                 if (i==0 ) return;
399                 device_menu(owi->devices[i-1]);
400         }
401 }
402
403 int main(int argc, char *argv[]) {
404         int i;
405         arg_t a;
406         //printf("Kommando: %s:\n", argv[0]);
407         while (--argc) {
408                 if (**++argv != '-') {
409         //printf("   Arg. = %s\n", *argv);
410         if (comlist.empty()) {
411                 a.flag=".";
412                 a.arg=*argv;
413                 comlist.push_back(a);
414         } else {
415                 if ((*(comlist.end()-1)).arg!="1") {
416                         a.flag=".";
417                         a.arg=*argv;
418                         comlist.push_back(a);
419                 } else {
420                         (*(comlist.end()-1)).arg=*argv;
421                 }
422         }
423                 } else {
424                         for( i=1; (*argv)[i] != '\0'; i++) {
425                                 //printf("   Flag = (%c)\n", (*argv)[i]);
426                                 a.flag=(*argv)[i];
427                                 a.arg="1";
428                                 comlist.push_back(a);
429                         }
430                 }
431     }          
432
433         //for(arg_t a:comlist) printf("%s->%s\n",a.flag.c_str(),a.arg.c_str());
434         if (getArg("h")=="1") {
435                 printhelp();
436                 return 0;
437         }
438         std::string adapter=getArg("a");
439         if (adapter.empty()) {
440                 printhelp();
441                 return 0;
442         }       
443         std::transform(adapter.begin(), adapter.end(),adapter.begin(), ::toupper);
444
445         std::string s;
446 #ifdef LINUX    
447         if(adapter.find("COM")!=std::string::npos) {
448                 owi=new owCOMInterface();
449                 int port=atoi(adapter.substr(adapter.find("COM")+3).c_str());
450                 printf("Open /dev/ttyS%i\n",port);
451                 owi->InitAdapter(port);
452         } else 
453         if(adapter.find("USB")!=std::string::npos) {
454                 owi=new owUSBInterface();
455                 int port=atoi(adapter.substr(adapter.find("USB")+3).c_str());
456                 printf("Open the %i. USB Adapter\n",port);
457                 int err;
458                 if ((err=owi->InitAdapter(port))<0) {
459                         if (err==-1) printf("No Adapter found!\n  On Linux, try: sudo owTools....\n  On Windows: Install libusb0 driver\n");
460                         if (err==-2) printf("Maybe Adapter is used ... (try sudo)\nOn Linux: If the kernel modul is loaded type: sudo rmmod ds2490\n");
461                         exit(0);
462                 }
463         } else 
464         if(adapter.find("GPIO")!=std::string::npos) {
465                 if (findCPU("BCM2708")) {
466                         printf("\033[1;33mRaspberry Pi 1 is dedected. 1-wire on the GPIO port can have many errors in the transfer.\033[0m\n");
467                         owi=new owPiGPioInterface();
468                         int port=atoi(adapter.substr(adapter.find("GPIO")+4).c_str());
469                         printf("Open GPIO %i\n",port);
470                 } else if (findCPU("BCM2709")) {
471                         owi=new owPiGPioInterface();
472                         int port=atoi(adapter.substr(adapter.find("GPIO")+4).c_str());
473                         printf("Open GPIO %i\n",port);
474                         owi->InitAdapter(port);
475                 } else {
476                         printf("\033[1;31mGPIO works with Raspberry PI only \033[0m\n");
477                 }
478         }  else
479 #endif
480         if (adapter.find("ARDUINO") != std::string::npos) {
481                 owi = new owARDUINOInterface();
482                 int port = atoi(adapter.substr(adapter.find("ARDUINO") + 7).c_str());
483                 printf("Open /dev/ttyS%i\n", port);
484                 owi->InitAdapter(port);
485         }
486
487 #ifdef WIN
488                 else 
489         if (adapter.find("USB") != std::string::npos) {
490                 printf("USB \n");
491                 owi = new owTMEXWIN();
492                 int port = atoi(adapter.substr(adapter.find("USB") + 3).c_str());
493                 printf("Open the %i. USB Adapter\n", port);
494                 int err;
495                 char cs[20];
496                 sprintf_s(cs, 20, "{%i,6}", port);
497                 if ((err = owi->InitAdapter(cs))==0) {
498                                         printf("ERROR Init USB Adapter\n");
499                                         exit(0);
500                                 }
501                         }
502         else
503                 if (adapter.find("COM") != std::string::npos) {
504                         printf("USB \n");
505                         owi = new owTMEXWIN();
506                         int port = atoi(adapter.substr(adapter.find("COM") + 3).c_str());
507                         printf("Open Adapter on COM%i\n", port);
508                         int err;
509                         char cs[20];
510                         sprintf_s(cs, 20, "{%i,5}", port);
511                         if ((err = owi->InitAdapter(cs))==0) {
512                                 printf("ERROR Init Serial Adapter\n");
513                                 exit(0);
514                         }
515                 }
516 #endif
517         if (owi == NULL) {
518                 printf("No 1-Wiremaster found\n");
519                 return 0;
520         }
521         setLogMode();
522         
523         
524
525         if (getArg("i")=="1") {
526                 interactive(owi);       
527         } else 
528         if (getArg("c")=="1") {
529                 int reload=(getArg("r")=="1");
530                 owi->Find();
531                 printf("\n");
532                 //owi->log->setLogLevel(3);
533                 std::string s;
534                 int pause;
535                 if ((s=getArg("p")) !="") {
536                         pause=atoi(s.c_str());
537                 } else pause=30;
538 #ifdef LINUX
539                 if  ((s=getArg("d")) !="") {
540                         reload=1;
541                         printf("Use Database\n");
542                         sdb=new mySensorDB(s,owi->log);
543                         if (sdb->log->last()>OWLOG_WARNING) {
544                                 exit(1);
545                         }
546                         sdb->connect();
547                         if (sdb->log->last()>OWLOG_WARNING) {
548                                 exit(1);
549                         }
550                         sdb->createSensorTable();
551                         if (sdb->log->last()>OWLOG_WARNING) {
552                                 exit(1);
553                         }                               
554                         database=1;
555                 }
556 #endif
557                         
558                 
559                 continuous(&(owi->devices),pause,1,reload);     
560         } else 
561         if ((s=getArg("f"))!="") {
562                 printf("Flash %s in selected Device\n",s.c_str());
563                 int sel=selectDevice();
564                 if (sel==0) exit(0);
565                 int resetid=questionYesNo("Would you reset to default ID? (This is necessary if another device is used!)");
566                 owi->log->setLogLevel(OWLOG_INFO);              
567                 owi->flashHEXFile(s,owi->device_nums[sel-1],resetid,1);
568                 setLogMode();
569                 owi->Clean();
570                 owi->Find();
571                 for (owDevice* dev :owi->devices) {
572                         snum_t snum=dev->getNum();
573                         printf("\033[1;34m%016llX\033[0m",(unsigned long long)snum.num);
574
575                         printf("\n");
576                 }
577                 printf("%i Devices found\n",(int)owi->devices.size());  
578                                 
579         } else 
580         if ((s=getArg("v"))!="") {
581                 printf("Reset VOC\n");
582                 int sel=selectDevice();
583                 if (sel==0) exit(0);
584                 owDevice* dev=owi->devices[sel-1];
585                 std::vector<uint8_t> cl;
586                 cl.push_back(0x4E);
587                 cl.push_back(0x1F);
588                 cl.push_back(0x1F);
589                 cl.push_back(0x1F);
590                 dev->Communicate(&cl,4,0);
591         } else 
592         
593         if ((s=getArg("n"))!="") {
594                 printf("Change id of selected Device\n");
595                 int sel=selectDevice();
596                 if (sel==0) exit(0);
597                 sel-=1;
598                 
599                 snum_t snum=owi->devices[sel]->getNum();
600                 if ((getArg("g"))=="1") {
601                         printf("get ID from Server\n");
602                         char s[255];
603 #ifdef LINUX
604                         sprintf(s,"wget -q http://www.tm3d.de/shop99/owid.php?fam=%02X -O id.txt",snum.byte[0]);
605 #endif
606 #ifdef WIN
607                         sprintf_s(s, "wget -q http://www.tm3d.de/shop99/owid.php?fam=%02X -O id.txt", snum.byte[0]);
608 #endif
609                         int err;
610                         if ((err=system(s))==0) {
611                                 printf("OK!\n");
612                                 std::string rs;
613                                 std::stringstream str;
614                                 std::ifstream fs;
615                                 fs.open ("id.txt" );
616                                 snum_t isnum;
617                                 int i=0; int br=0;
618                                 if(fs.is_open()) {
619                                 while(fs.peek() != EOF) {
620                                         char c= (char) fs.get();
621                                         if (br==0) {
622                                                 if (c=='x') br=1;
623                                         } else {
624                                                 if ((c==',')|(c=='}')) {
625                                                         isnum.byte[i]=(uint8_t)strtol(s, NULL, 16);
626                                                         //printf("%x\n",strtol(s, NULL, 16));
627                                                         i++;
628                                                         br=0;
629                                                         s[0]=0;
630                                                 } else {
631                                                         s[br-1]=c;
632                                                         s[br]=0;
633                                                         br++;
634                                                 }
635                                         }
636                                         if (c=='}') break;
637                                 }
638                                 
639                                 fs.close();
640                                 }                                         
641                                 snum.num=isnum.num;
642                         } else (printf("ERROR %i\n",err));
643                 } else {
644                         snum.num+=256;
645                 }
646
647
648                 printf("New ID: ");
649                 printf("\033[1;34m%016llX\033[0m",(unsigned long long)snum.num);
650
651                 printf("\n");
652                 
653                 owi->devices[sel]->changeID(snum);              
654         
655                 owi->Clean();
656                 owi->Find();
657                 for (owDevice* dev :owi->devices) {
658                         snum_t snum=dev->getNum();
659                         printf("\033[1;34m%016llX\033[0m",(unsigned long long)snum.num);
660
661                         printf("\n");
662                 }
663                 printf("%i Devices found\n",(int)owi->devices.size());  
664                                 
665         } else {
666                 owi->Find();
667                 for (owDevice* dev :owi->devices) {
668                         printf("_______________________________________________________________________\n");
669                         snum_t snum=dev->getNum();
670                         printf("\033[1;34m%016llX\033[0m ",(unsigned long long)snum.num);
671                         switch (dev->configstate) {
672                                 case OWDCS_16:printf("old Configcode from www.tm3d.de");break;
673                                 case OWDCS_24:printf("Configcode from www.tm3d.de");break;
674                                 case OWDCS_DEFAULT:printf("Default Configcode set by this Software");break;
675                                 case OWDCS_NONE:printf("No Configcode");break;
676                         }
677                         printf( " - (");
678                         for(int i=0;i<3;i++)
679                                 printf(" %s",dev->getFamilyInfo()[i].c_str());
680                         printf(" )\n");
681                         if (dev->configstate!=OWDCS_NONE) {
682                                 std::vector<std::vector<std::string>> ia;
683                                 std::vector<size_t> maxcol;
684                                 dev->convertAll();
685                                 for(int i=0;i<4;i++) {
686                                         std::vector<std::string> colm;
687                                         size_t max=0;
688                                         colm.push_back(dev->config->getSensorChip(i));
689                                         if (max<utf8_length(colm[0])) max=utf8_length(colm[0]);
690                                         colm.push_back(dev->config->getQuantity(i));
691                                         if (max<utf8_length(colm[1])) max=utf8_length(colm[1]);
692                                         colm.push_back(dev->config->getUnit(i));
693                                         if (max<utf8_length(colm[2])) max=utf8_length(colm[2]);
694                                         if (dev->config->getPropertyID(i)==0) {
695                                                 colm.push_back("");
696                                         } else {
697                                                 char hs[50];
698 #ifdef LINUX
699                                                 sprintf(hs,"%0.3f",dev->values[i]);
700 #endif
701 #ifdef WIN
702                                                 sprintf_s(hs, "%0.3f", dev->values[i]);
703 #endif
704                                                 colm.push_back(hs);
705                                         }
706                                         if (max<utf8_length(colm[3])) max=utf8_length(colm[3]);
707                                         ia.push_back(colm);
708                                         maxcol.push_back(max);
709                                 }
710                                 std::string space="                                                          ";
711                                 for(int i=0;i<4;i++) {
712                                         for(int j=0;j<4;j++) {
713                                                 printf("%s%s",ia[j][i].c_str(),space.substr(0,maxcol[j]-utf8_length(ia[j][i])+2).c_str());
714                                         }
715                                         printf("\n");
716                                 }
717                         }
718                 }
719                 printf("%i Devices found\n",(int)owi->devices.size());
720         }
721         return 0;
722    
723 }