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