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