Sungo SXL MQTT Anbindung

Aus TippvomTibb
Zur Navigation springen Zur Suche springen

Allgemeines

Nach einer kleinen Pause (5 Monate) versuche ich die SunGO SXL Anbindung aus dem Versuchstadium zu befreien und mal alles ordentlich zu machen. Die Hardware kommt in eine Gehäuse und die Software soll ihren ersten Stresztest bestehen.

Ausgangssituation

SunGO Raspi Interface roh.jpg

Abgesehen von der SunGo SXL Steuerung sind aktuelle noch ein RasPi 3B, ein CP2102 USBSER und Arduino NANO und 4 DS18B20 im Einsatz. Das Netzteil ist nur eine Übergangslösung. Am liebsten wuerde ich eine MiniUSV mit ins Gehaeuse packen. Mal schauen was es da von der Stange gibt. Auf dem RasPi laeuft derzeit nur eine Software die die Aufgabe hat die Daten des SunGo-Interfaces und die Temperaturen der 4 DS18B20 (Vor-/Ruecklauf-Heizkreis1 und Vor-/Ruecklauf-Fuszbodenheizung) einzulesen und per MQTT an den FHEM-Broker (MQTT-Server) zu liefern.


Software

Verdammt! Nach 5 Monaten raecht sich die fehlende Dokumentation.


Sungo_MQTT

Sungo_MQTT.c
   1 #include <string.h>
   2 #include <stdlib.h>
   3 #include <stdio.h>
   4 #include <unistd.h>
   5 #include <stdbool.h>
   6 #include <time.h>
   7 #include <sys/types.h>
   8 #include <sys/stat.h>
   9 #include <fcntl.h>
  10 #include <termios.h> // termios is the API that is in general recommended for serial I/O in Unix.
  11 #include "MQTTClient.h"
  12 
  13 // MQTT defines
  14 #define ADDRESS     "tcp://192.168.178.12:1883"
  15 //#define ADDRESS     "tcp://localhost:1883"
  16 #define CLIENTID    "SunGo"
  17 //#define TOPIC       "MQTTExamples"
  18 //#define PAYLOAD     "Hello World!"
  19 #define QOS         0
  20 #define TIMEOUT     10000L
  21 
  22 // SERCOM defines
  23 #define BAUDRATE B115200
  24 #define MODEMDEVICE "/dev/ttyS1"
  25 #define _POSIX_SOURCE 1 /* POSIX compliant source */
  26 #define FALSE 0
  27 #define TRUE 1
  28 
  29 
  30 // SunGo defines
  31 #define DUMMY       0
  32 #define TEMPERATUR  1   // °C
  33 #define STRAHLUNG   2   // W/m²     
  34 #define SPEICHER1    7   // kwh
  35 #define DATUM      8
  36 #define UHRZEIT     9
  37 #define PROZENT     10  // %
  38 #define FUNKTION1   11
  39 #define FUNKTION2   12
  40 #define SPEICHER2    15 // h
  41 #define VOLUMENSTROM 19 // l/min
  42 
  43 
  44 volatile int STOP=FALSE; // braucht man eigentlich nicht Man koennte z.B. um die Endlosschleife elegant zu verlassen durch einen Taster mit ISR die globale Variabe STOP auf true setzen
  45 // solange das nicht realisiert ist laeuft die "main-Schleife" endlos.
  46 
  47 
  48 // globale Variablen 
  49 char datum[11];
  50 char uhrzeit[7];
  51 char temperatur[25];
  52 char prozent[7];
  53 char strahlung[8];
  54 char fehler[17];
  55 char stunden[8];
  56 char dummy[7];
  57 
  58 // hexadezimale Darstellung in dezimale umstellen
  59 unsigned int hextodec(char hex[10]){
  60   unsigned int decimal=0;
  61   unsigned int length=0;
  62   unsigned int base = 1;
  63   int i=0;
  64   
  65   while(hex[i]!='\0'){
  66     i++;
  67   }
  68   length=i;
  69 
  70     //printf("hextodec %s\n\r",hex);
  71     //printf("length %d\n\r",length);
  72   
  73   for(i = length-1; i >= 0; i--){
  74     //printf("i: %d\n\r",i); 
  75     if (i<0)i=0;
  76       if(hex[i] >= '0' && hex[i] <= '9'){
  77         decimal += ((unsigned char)hex[i] - 48) * base;
  78         base *= 16;
  79       }
  80       else if(hex[i] >= 'A' && hex[i] <= 'F'){
  81         decimal += ((unsigned char)hex[i] - 55) * base;
  82         base *= 16;
  83       }
  84       else if(hex[i] >= 'a' && hex[i] <= 'f'){
  85         decimal += ((unsigned char)hex[i] - 87) * base;
  86         base *= 16;
  87       }
  88   }
  89   //printf("decimal %d\n\r",decimal);
  90   return decimal;
  91 }
  92 
  93 void delay(int number_of_seconds) // wird doch nicht gebraucht
  94 {
  95     // Converting time into milli_seconds
  96     int milli_seconds = 1000 * number_of_seconds;
  97   
  98     // Storing start time
  99     clock_t start_time = clock();
 100   
 101     // looping till required time is not achieved
 102     while (clock() < start_time + milli_seconds)
 103         ;
 104 }
 105 
 106 // allgemeine Funktion; die verschiedenen Typen werden ueber switch case angesprochen  
 107 void formatieren(unsigned char typ,unsigned char lowbyte,unsigned char highbyte){
 108     char data[10]="";   // dient der Aufnahme des zu wandelnden Wertes gebildet aus highbyte und lowbyte
 109     char tmp[3]="";     // hilfvariable
 110     char formatted[25]="";
 111     char dataStr[5]="";
 112     unsigned int dataInteger;
 113     float dataFloat;
 114     unsigned int dataStunden, dataMinuten;
 115 
 116     //memset(formatted,'\0',sizeof(formatted));
 117     //memset(data,'\0',sizeof(data)); 
 118     //memset(tmp,'\0',sizeof(tmp)); 
 119     
 120     // aus den beiden Einzelwerten wird der "Gesamtwert in der "richtigen" Reihenfolge gebildet
 121     sprintf(tmp,"%02X",highbyte);
 122     strcpy(data,tmp);
 123     sprintf(tmp,"%02X",lowbyte);
 124     strcat(data,tmp);
 125  
 126     //printf("Data: %s\n",data);
 127     
 128     dataInteger=hextodec(data);
 129  
 130    switch(typ) {
 131 	case DUMMY:         if(TRUE){
 132                             strcpy(dummy,data);
 133                         }
 134                         else{
 135                             strcpy(dummy,"Error!");
 136                         } 
 137                         break;
 138     case DATUM:         sprintf(dataStr,"%d",dataInteger);
 139                         strcpy(formatted,"00.00.2021");
 140                         if(strlen(dataStr)==3){
 141                             formatted[0]=dataStr[1];  
 142                             formatted[1]=dataStr[2]; 
 143                             formatted[4]=dataStr[0]; 
 144                             strcpy(datum,formatted);
 145                         }
 146                         else if(strlen(dataStr)==4){
 147                             formatted[0]=dataStr[2];  
 148                             formatted[1]=dataStr[3]; 
 149                             formatted[3]=dataStr[0]; 
 150                             formatted[4]=dataStr[1]; 
 151                             strcpy(datum,formatted);
 152                         }   
 153                         else{
 154                             strcpy(datum,"Error!");
 155                         }
 156                         break;
 157 	case UHRZEIT:       dataStunden=(unsigned int)dataInteger/60;
 158                         dataMinuten=dataInteger-(dataStunden*60);
 159                         if(TRUE){ // hier koennte man die gueltig der stunden und minuten noch testen 
 160                             sprintf(formatted,"%02d:%02d",dataStunden,dataMinuten);
 161                             strcpy(uhrzeit,formatted);
 162                         }
 163                         else{
 164                             strcpy(uhrzeit,"Error!");
 165                         }
 166                         break;
 167     case TEMPERATUR:   dataFloat=(float)dataInteger/10.0;
 168                         if(TRUE){
 169                             //sprintf(formatted,"%5.1f °C (%d)     ",dataFloat,dataInteger);
 170                             sprintf(formatted,"%5.1f °C",dataFloat);
 171                             strcpy(temperatur,formatted);
 172                         }
 173                         else{
 174                             strcpy(temperatur,"Error!\0");
 175                         }
 176                         break;
 177     case SPEICHER2:     if(TRUE){
 178                             sprintf(formatted,"%dh",dataInteger);
 179                             strcpy(stunden,formatted);
 180                         }
 181                         else{
 182                             strcpy(stunden,"Error!");
 183                         }
 184                         break;
 185     case PROZENT:       if(TRUE){
 186                             sprintf(formatted,"%3d%%",dataInteger);
 187                             strcpy(prozent,formatted);
 188                         }
 189                         else{
 190                             strcpy(prozent,"Error!");
 191                         }
 192                         break;     
 193     case STRAHLUNG:     if(TRUE){
 194                             sprintf(formatted,"%d W/m²    ",dataInteger);
 195                             strcpy(strahlung,formatted);
 196                         }
 197                         else{
 198                             strcpy(strahlung,"Error!\0");
 199                         }
 200                         break; 
 201 	default:            printf("Type Error (unknown)\n"); break;
 202     } 
 203     
 204      return;
 205 }
 206 
 207 int main(int argc, char **argv)
 208 {   int i;                                  // Schleifenzaehler allgemein
 209     unsigned int state=0, syncstate=0;      // state 10,20,30 oder 31 entsprechend 0100, 0200, 0300, 0301
 210     unsigned int dsIndex, dfIndex;          // Zeiger auf Datensatz und Datenfeld
 211     unsigned long zeitzaehler=0;            // Ausgabe verlangsamen 500000 etwa 1 Minute
 212    
 213     unsigned char buf[1];
 214     unsigned char merker[6];
 215     unsigned char datensatz[100];
 216     unsigned char datenfeld[100];
 217     unsigned char datenfelder[50][16];
 218     bool printflag;
 219 
 220     // MQTT Vorbereitung
 221     MQTTClient client;
 222     MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
 223     MQTTClient_message pubmsg = MQTTClient_message_initializer;
 224     MQTTClient_deliveryToken token;
 225     int mqttrc;                             // 
 226     char topic[255];                        // zur Aufnahme Werte unterhalb des basetopic
 227     char *basetopic = "Haus/Heizung/Solaranlage/SunGo/";
 228     
 229     // MQTT Cleint Struktur anlegen
 230     if ((mqttrc = MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS){
 231          printf("Failed to create mqttclient, return code %d\n", mqttrc);
 232          exit(EXIT_FAILURE);
 233     }
 234 
 235    // SerCOM Vorbereitung
 236     struct termios oldtio,newtio;
 237     int fd; // FileDescriptor SerCOM
 238     int res; // SerCOM Einlesekontrolle
 239     
 240     // wenn in Kommandozeile die Schnittstelle mitgegeben wird, dann nimm diese sonst versuche default
 241     if (argc > 1)
 242         fd = open(argv[1], O_RDWR | O_NOCTTY );
 243     else
 244         fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
 245     if (fd <0) {
 246         perror(MODEMDEVICE); 
 247         exit(-1); 
 248     }
 249 
 250     // sichere die aktuellen Einstellungen
 251     tcgetattr(fd,&oldtio); 
 252     
 253     // baue die neuen Einstellungen zusammen
 254     bzero(&newtio, sizeof(newtio));
 255     newtio.c_cflag = BAUDRATE |  CS8 | CLOCAL | CREAD;
 256     newtio.c_iflag = IGNPAR | IXON | IXOFF;
 257     newtio.c_oflag = 0;
 258     newtio.c_lflag = 0; 
 259     newtio.c_cc[VTIME]    = 0;   /* inter-character timer unused */
 260     newtio.c_cc[VMIN]     = 1;   /* blocking read until 1 chars received */
 261 
 262     tcflush(fd, TCIFLUSH);
 263     tcsetattr(fd,TCSANOW,&newtio);
 264    
 265     setvbuf(stdout, (char *)NULL, _IONBF, 0);
 266     
 267     // hier sind alle Vorbereitungen (SERCOM, MQTT) abgeschlossen jetzt koennen die Daten des Interfaces eingelesen, aufbereitet und per MQTT gesendet werden
 268     // Die 4 verschiedenen denkbaren Pakete (DPA_1, DPA_2, DPB_1, DPB_2) beginnen alle mit AA 55 55 AA (DEZ: 170 85 85 170)
 269     // wenn diese Folge erkannt wird bestimmen die beiden folgenden Bytes den Typ des Paketes
 270     while (STOP==FALSE) {   // Endlosschleife 
 271  
 272          res = read(fd,buf,1);   
 273   
 274         //sobald ein AA kommt beginne die Beobachtung
 275         if ((buf[0]==170) && (syncstate==5)){
 276             syncstate=0;
 277         }
 278         if ((buf[0]==170) && (syncstate==0)){  // wenn der syncstate 0 (gleich Anfang) und ein AA erkannt wird dann setze sysncstate=1
 279             syncstate=1;
 280             merker[0]=buf[0];
 281         }
 282         if ((buf[0]==85) && (syncstate==1)){    // wenn der syncstate 1 (AA bereits erkannt) und ein 55 erkannt wird dann setze sysncstate=2
 283             syncstate=2;
 284             merker[1]=buf[0];
 285         }
 286         if ((buf[0]==85) && (syncstate==2)){    // wenn der syncstate 2 (AA 55 bereits erkannt) und ein 55 erkannt wird dann setze sysncstate=3
 287             syncstate=3;
 288             merker[2]=buf[0];
 289         }
 290         if ((buf[0]==170) && (syncstate==3)){    // wenn der syncstate 3 (AA 55 55 bereits erkannt) und ein AA erkannt wird dann setze sysncstate=4
 291             syncstate=4;
 292             merker[3]=buf[0];
 293             state=0;
 294         }
 295         // wenn AA 55 55 AA erkannt wurde steht syncstate auf 4 , in merker[0-3] befindet sich die Syncfolge und state ist 0
 296         // wenn das nachfolgende Byte entweder 01 02 oder 03 ist ist alles wie erwartet und kann weitergehen syncstate = 5
 297         if (((buf[0]==1)||(buf[0]==2)||(buf[0]==3)) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==4)){
 298             merker[4]=buf[0];
 299             syncstate=5;
 300         }   
 301         // ab hier werden die 4 Pakete unterschieden DPA_1 0200 (state 20), DPA_2 0100 (state 10), DPB_1 0301 (state 31) und DPB_2 0300 (state 30)
 302  
 303         if ((buf[0]==0) && (merker[4]==1) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){
 304             state=10; // state 10 bereit fuer 0100  Daten fuer das LC-Display
 305             printflag=FALSE;
 306             for(i=0;i<5;i++)merker[i]=0;
 307  
 308         }
 309         if ((buf[0]==0) && (merker[4]==2) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){
 310             state=20; // state 20 bereit fuer 0200 hat keinen (?) Inhalt -> keine Auswertung 
 311             printflag=FALSE;
 312             for(i=0;i<5;i++)merker[i]=0;
 313      
 314         }
 315         if ((buf[0]==0) && (merker[4]==3) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){
 316             state=30; // state 30 bereit fuer 0300 Datensatze
 317             printflag=FALSE;
 318             for(i=0;i<5;i++)merker[i]=0;
 319             dsIndex=0;
 320  
 321         }
 322         if ((buf[0]==1) && (merker[4]==3) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){
 323             state=31; // state 31 bereit fuer 0301 Datenfaelder
 324             printflag=FALSE;
 325             for(i=0;i<5;i++)merker[i]=0;
 326             dfIndex=0;
 327 
 328         }
 329         
 330  
 331         // state 10 und 20 werden nicht ausgewertet        
 332         if ((state==10) && printflag) {
 333 
 334         }
 335         else if ((state==20) && printflag) {
 336  
 337         }
 338         else if ((state==30)  && printflag){
 339  
 340             if(dsIndex<100)datensatz[dsIndex++]=buf[0];
 341         }
 342         else if ((state==31) && printflag) {
 343  
 344             if(dfIndex<100)datenfeld[dfIndex++]=buf[0];
 345         }
 346         else{
 347          //printf("syncstate: %d, state: %d, %X\n\r",syncstate,state,buf[0]);   
 348         }
 349 
 350         printflag=TRUE;
 351  
 352         if (zeitzaehler==10000){
 353             // es wird etwa 3 mal pro Minute eine Auswahl der Datensaetze ausgegeben
 354             // Datum: 18.09.2021
 355             // Message published, return code 0
 356             // Uhrzeit: 12:17
 357             // Message published, return code 0
 358             // Kollektor:  58.6 °C
 359             // Message published, return code 0
 360             // Speicher unten:  49.2 °C
 361             // Message published, return code 0
 362             // Speicher oben:  52.1 °C
 363             // Message published, return code 0
 364             // Rücklaufanhebung T7:  52.0 °C
 365             // Message published, return code 0
 366             // Rücklaufanhebung T8:  28.1 °C
 367             // Message published, return code 0
 368             // Ausgang 1:  60%
 369             // Message published, return code 0
 370             // Ausgang 6: 100%
 371             // Message published, return code 0
 372             // Speicher 2: 15632h
 373             // Message published, return code 0
 374 
 375             conn_opts.keepAliveInterval = 20;
 376             conn_opts.cleansession = 1;
 377             // Baue MQTT Verbindung auf
 378             if ((mqttrc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS){
 379                 printf("Failed to connect, return code %d\n", mqttrc);
 380                 exit(EXIT_FAILURE);
 381             }
 382             //Datum
 383             formatieren(DATUM,datensatz[2],datensatz[3]);
 384             printf("Datum: %s\n",datum); 
 385             strcpy(topic,basetopic);
 386             strcat(topic,"Datum");
 387             pubmsg.payload = datum;
 388             pubmsg.payloadlen = (int)strlen(datum);
 389             pubmsg.qos = QOS;
 390             pubmsg.retained = 0;
 391             if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
 392                 printf("Failed to publish message, return code %d\n", mqttrc);
 393                 exit(EXIT_FAILURE);
 394             }else{
 395                 printf("Message published, return code %d\n", mqttrc); 
 396             }  
 397             //Uhrzeit
 398             formatieren(UHRZEIT,datensatz[4],datensatz[5]);
 399             printf("Uhrzeit: %s\n",uhrzeit);
 400             strcpy(topic,basetopic);            
 401             strcat(topic,"Uhrzeit");            
 402             pubmsg.payload = uhrzeit;
 403             pubmsg.payloadlen = (int)strlen(uhrzeit);
 404             pubmsg.qos = QOS;
 405             pubmsg.retained = 0;
 406             if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
 407                 printf("Failed to publish message, return code %d\n", mqttrc);
 408                 exit(EXIT_FAILURE);
 409             }else{
 410                 printf("Message published, return code %d\n", mqttrc); 
 411             } 
 412             //Kollektor
 413             formatieren(TEMPERATUR,datensatz[6],datensatz[7]);
 414             printf("Kollektor: %s\n",temperatur);
 415             strcpy(topic,basetopic);            
 416             strcat(topic,"Kollektor/Temperatur");
 417             pubmsg.payload = temperatur;
 418             pubmsg.payloadlen = (int)strlen(temperatur);
 419             pubmsg.qos = QOS;
 420             pubmsg.retained = 0;
 421             if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
 422                 printf("Failed to publish message, return code %d\n", mqttrc);
 423                 exit(EXIT_FAILURE);
 424             }else{
 425                 printf("Message published, return code %d\n", mqttrc); 
 426             }
 427              //Speicher unten
 428             formatieren(TEMPERATUR,datensatz[8],datensatz[9]);
 429             printf("Speicher unten: %s\n",temperatur);
 430             strcpy(topic,basetopic);            
 431             strcat(topic,"Speicher/unten/Temperatur");
 432             pubmsg.payload = temperatur;
 433             pubmsg.payloadlen = (int)strlen(temperatur);
 434             pubmsg.qos = QOS;
 435             pubmsg.retained = 0;
 436             if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
 437                 printf("Failed to publish message, return code %d\n", mqttrc);
 438                 exit(EXIT_FAILURE);
 439             }else{
 440                 printf("Message published, return code %d\n", mqttrc); 
 441             }
 442             //Speicher oben
 443             formatieren(TEMPERATUR,datensatz[10],datensatz[11]);
 444             printf("Speicher oben: %s\n",temperatur);
 445             strcpy(topic,basetopic);            
 446             strcat(topic,"Speicher/oben/Temperatur");
 447             pubmsg.payload = temperatur;
 448             pubmsg.payloadlen = (int)strlen(temperatur);
 449             pubmsg.qos = QOS;
 450             pubmsg.retained = 0;
 451             if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
 452                 printf("Failed to publish message, return code %d\n", mqttrc);
 453                 exit(EXIT_FAILURE);
 454             }else{
 455                 printf("Message published, return code %d\n", mqttrc); 
 456             } 
 457             //Rücklaufanhebung T7
 458             formatieren(TEMPERATUR,datensatz[18],datensatz[19]);
 459             printf("Rücklaufanhebung T7: %s\n",temperatur);
 460             strcpy(topic,basetopic);            
 461             strcat(topic,"Rücklaufanhebung/T7/Temperatur");
 462             pubmsg.payload = temperatur;
 463             pubmsg.payloadlen = (int)strlen(temperatur);
 464             pubmsg.qos = QOS;
 465             pubmsg.retained = 0;
 466             if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
 467                 printf("Failed to publish message, return code %d\n", mqttrc);
 468                 exit(EXIT_FAILURE);
 469             }else{
 470                 printf("Message published, return code %d\n", mqttrc); 
 471             }              
 472             //Rücklaufanhebung T8
 473             formatieren(TEMPERATUR,datensatz[20],datensatz[21]);
 474             printf("Rücklaufanhebung T8: %s\n",temperatur);
 475             strcpy(topic,basetopic);            
 476             strcat(topic,"Rücklaufanhebung/T8/Temperatur");
 477             pubmsg.payload = temperatur;
 478             pubmsg.payloadlen = (int)strlen(temperatur);
 479             pubmsg.qos = QOS;
 480             pubmsg.retained = 0;
 481             if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
 482                 printf("Failed to publish message, return code %d\n", mqttrc);
 483                 exit(EXIT_FAILURE);
 484             }else{
 485                 printf("Message published, return code %d\n", mqttrc); 
 486             } 
 487            //Ausgang 1
 488             formatieren(PROZENT,datensatz[32],0);
 489             printf("Ausgang 1: %s\n",prozent);
 490             strcpy(topic,basetopic);            
 491             strcat(topic,"Ausgang/1/Prozent");
 492             pubmsg.payload = prozent;
 493             pubmsg.payloadlen = (int)strlen(prozent);
 494             pubmsg.qos = QOS;
 495             pubmsg.retained = 0;
 496             if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
 497                 printf("Failed to publish message, return code %d\n", mqttrc);
 498                 exit(EXIT_FAILURE);
 499             }else{
 500                 printf("Message published, return code %d\n", mqttrc); 
 501             }  
 502            //Ausgang 6
 503             formatieren(PROZENT,datensatz[37],0);
 504             printf("Ausgang 6: %s\n",prozent);
 505             strcpy(topic,basetopic);            
 506             strcat(topic,"Ausgang/6/Prozent");
 507             pubmsg.payload = prozent;
 508             pubmsg.payloadlen = (int)strlen(prozent);
 509             pubmsg.qos = QOS;
 510             pubmsg.retained = 0;
 511             if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
 512                 printf("Failed to publish message, return code %d\n", mqttrc);
 513                 exit(EXIT_FAILURE);
 514             }else{
 515                 printf("Message published, return code %d\n", mqttrc); 
 516             }  
 517             // Speicherstunden
 518             formatieren(SPEICHER2,datensatz[50],datensatz[51]);
 519             printf("Speicher 2: %s\n",stunden);
 520             strcpy(topic,basetopic);            
 521             strcat(topic,"Speicher/Stunden");
 522             pubmsg.payload = stunden;
 523             pubmsg.payloadlen = (int)strlen(stunden);
 524             pubmsg.qos = QOS;
 525             pubmsg.retained = 0;
 526             if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
 527                 printf("Failed to publish message, return code %d\n", mqttrc);
 528                 exit(EXIT_FAILURE);
 529             }else{
 530                 printf("Message published, return code %d\n", mqttrc); 
 531             }  
 532     /*    printf("Waiting for up to %d seconds for publication of %s\n"
 533                 "on topic %s for client with ClientID: %s\n",
 534                 (int)(TIMEOUT/1000), PAYLOAD, TOPIC, CLIENTID);
 535         rc = MQTTClient_waitForCompletion(client, token, TIMEOUT);
 536         printf("Message with delivery token %d delivered\n", token);
 537     */
 538             if ((mqttrc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS){
 539                 printf("Failed to disconnect, return code %d\n", mqttrc);
 540             }
 541             zeitzaehler=0;
 542         }
 543         zeitzaehler++;
 544         if (zeitzaehler%100000==0)printf("%d\n",zeitzaehler); // Lebenszeichen
 545       
 546     }
 547     
 548     close(fd);                      // schliesze serielle Schnittstelle
 549     
 550     tcsetattr(fd,TCSANOW,&oldtio);  // stelle die alte ComConfig wieder her
 551    
 552     MQTTClient_destroy(&client);    // beende die MQTT Kommunikation
 553     
 554     return EXIT_SUCCESS;
 555 }
 556 #include <string.h>
 557 #include <stdlib.h>
 558 #include <stdio.h>
 559 #include <unistd.h>
 560 #include <stdbool.h>
 561 #include <time.h>
 562 #include <sys/types.h>
 563 #include <sys/stat.h>
 564 #include <fcntl.h>
 565 #include <termios.h> // termios is the API that is in general recommended for serial I/O in Unix.
 566 #include "MQTTClient.h"
 567 
 568 // MQTT defines
 569 #define ADDRESS     "tcp://192.168.178.12:1883"
 570 //#define ADDRESS     "tcp://localhost:1883"
 571 #define CLIENTID    "SunGo"
 572 //#define TOPIC       "MQTTExamples"
 573 //#define PAYLOAD     "Hello World!"
 574 #define QOS         0
 575 #define TIMEOUT     10000L
 576 
 577 // SERCOM defines
 578 #define BAUDRATE B115200
 579 #define MODEMDEVICE "/dev/ttyS1"
 580 #define _POSIX_SOURCE 1 /* POSIX compliant source */
 581 #define FALSE 0
 582 #define TRUE 1
 583 
 584 
 585 // SunGo defines
 586 #define DUMMY       0
 587 #define TEMPERATUR  1   // °C
 588 #define STRAHLUNG   2   // W/m²     
 589 #define SPEICHER1    7   // kwh
 590 #define DATUM      8
 591 #define UHRZEIT     9
 592 #define PROZENT     10  // %
 593 #define FUNKTION1   11
 594 #define FUNKTION2   12
 595 #define SPEICHER2    15 // h
 596 #define VOLUMENSTROM 19 // l/min
 597 
 598 
 599 volatile int STOP=FALSE; // braucht man eigentlich nicht Man koennte z.B. um die Endlosschleife elegant zu verlassen durch einen Taster mit ISR die globale Variabe STOP auf true setzen
 600 // solange das nicht realisiert ist laeuft die "main-Schleife" endlos.
 601 
 602 
 603 // globale Variablen 
 604 char datum[11];
 605 char uhrzeit[7];
 606 char temperatur[25];
 607 char prozent[7];
 608 char strahlung[8];
 609 char fehler[17];
 610 char stunden[8];
 611 char dummy[7];
 612 
 613 // hexadezimale Darstellung in dezimale umstellen
 614 unsigned int hextodec(char hex[10]){
 615   unsigned int decimal=0;
 616   unsigned int length=0;
 617   unsigned int base = 1;
 618   int i=0;
 619   
 620   while(hex[i]!='\0'){
 621     i++;
 622   }
 623   length=i;
 624 
 625     //printf("hextodec %s\n\r",hex);
 626     //printf("length %d\n\r",length);
 627   
 628   for(i = length-1; i >= 0; i--){
 629     //printf("i: %d\n\r",i); 
 630     if (i<0)i=0;
 631       if(hex[i] >= '0' && hex[i] <= '9'){
 632         decimal += ((unsigned char)hex[i] - 48) * base;
 633         base *= 16;
 634       }
 635       else if(hex[i] >= 'A' && hex[i] <= 'F'){
 636         decimal += ((unsigned char)hex[i] - 55) * base;
 637         base *= 16;
 638       }
 639       else if(hex[i] >= 'a' && hex[i] <= 'f'){
 640         decimal += ((unsigned char)hex[i] - 87) * base;
 641         base *= 16;
 642       }
 643   }
 644   //printf("decimal %d\n\r",decimal);
 645   return decimal;
 646 }
 647 
 648 void delay(int number_of_seconds) // wird doch nicht gebraucht
 649 {
 650     // Converting time into milli_seconds
 651     int milli_seconds = 1000 * number_of_seconds;
 652   
 653     // Storing start time
 654     clock_t start_time = clock();
 655   
 656     // looping till required time is not achieved
 657     while (clock() < start_time + milli_seconds)
 658         ;
 659 }
 660 
 661 // allgemeine Funktion; die verschiedenen Typen werden ueber switch case angesprochen  
 662 void formatieren(unsigned char typ,unsigned char lowbyte,unsigned char highbyte){
 663     char data[10]="";   // dient der Aufnahme des zu wandelnden Wertes gebildet aus highbyte und lowbyte
 664     char tmp[3]="";     // hilfvariable
 665     char formatted[25]="";
 666     char dataStr[5]="";
 667     unsigned int dataInteger;
 668     float dataFloat;
 669     unsigned int dataStunden, dataMinuten;
 670 
 671     //memset(formatted,'\0',sizeof(formatted));
 672     //memset(data,'\0',sizeof(data)); 
 673     //memset(tmp,'\0',sizeof(tmp)); 
 674     
 675     // aus den beiden Einzelwerten wird der "Gesamtwert in der "richtigen" Reihenfolge gebildet
 676     sprintf(tmp,"%02X",highbyte);
 677     strcpy(data,tmp);
 678     sprintf(tmp,"%02X",lowbyte);
 679     strcat(data,tmp);
 680  
 681     //printf("Data: %s\n",data);
 682     
 683     dataInteger=hextodec(data);
 684  
 685    switch(typ) {
 686 	case DUMMY:         if(TRUE){
 687                             strcpy(dummy,data);
 688                         }
 689                         else{
 690                             strcpy(dummy,"Error!");
 691                         } 
 692                         break;
 693     case DATUM:         sprintf(dataStr,"%d",dataInteger);
 694                         strcpy(formatted,"00.00.2021");
 695                         if(strlen(dataStr)==3){
 696                             formatted[0]=dataStr[1];  
 697                             formatted[1]=dataStr[2]; 
 698                             formatted[4]=dataStr[0]; 
 699                             strcpy(datum,formatted);
 700                         }
 701                         else if(strlen(dataStr)==4){
 702                             formatted[0]=dataStr[2];  
 703                             formatted[1]=dataStr[3]; 
 704                             formatted[3]=dataStr[0]; 
 705                             formatted[4]=dataStr[1]; 
 706                             strcpy(datum,formatted);
 707                         }   
 708                         else{
 709                             strcpy(datum,"Error!");
 710                         }
 711                         break;
 712 	case UHRZEIT:       dataStunden=(unsigned int)dataInteger/60;
 713                         dataMinuten=dataInteger-(dataStunden*60);
 714                         if(TRUE){ // hier koennte man die gueltig der stunden und minuten noch testen 
 715                             sprintf(formatted,"%02d:%02d",dataStunden,dataMinuten);
 716                             strcpy(uhrzeit,formatted);
 717                         }
 718                         else{
 719                             strcpy(uhrzeit,"Error!");
 720                         }
 721                         break;
 722     case TEMPERATUR:   dataFloat=(float)dataInteger/10.0;
 723                         if(TRUE){
 724                             //sprintf(formatted,"%5.1f °C (%d)     ",dataFloat,dataInteger);
 725                             sprintf(formatted,"%5.1f °C",dataFloat);
 726                             strcpy(temperatur,formatted);
 727                         }
 728                         else{
 729                             strcpy(temperatur,"Error!\0");
 730                         }
 731                         break;
 732     case SPEICHER2:     if(TRUE){
 733                             sprintf(formatted,"%dh",dataInteger);
 734                             strcpy(stunden,formatted);
 735                         }
 736                         else{
 737                             strcpy(stunden,"Error!");
 738                         }
 739                         break;
 740     case PROZENT:       if(TRUE){
 741                             sprintf(formatted,"%3d%%",dataInteger);
 742                             strcpy(prozent,formatted);
 743                         }
 744                         else{
 745                             strcpy(prozent,"Error!");
 746                         }
 747                         break;     
 748     case STRAHLUNG:     if(TRUE){
 749                             sprintf(formatted,"%d W/m²    ",dataInteger);
 750                             strcpy(strahlung,formatted);
 751                         }
 752                         else{
 753                             strcpy(strahlung,"Error!\0");
 754                         }
 755                         break; 
 756 	default:            printf("Type Error (unknown)\n"); break;
 757     } 
 758     
 759      return;
 760 }
 761 
 762 int main(int argc, char **argv)
 763 {   int i;                                  // Schleifenzaehler allgemein
 764     unsigned int state=0, syncstate=0;      // state 10,20,30 oder 31 entsprechend 0100, 0200, 0300, 0301
 765     unsigned int dsIndex, dfIndex;          // Zeiger auf Datensatz und Datenfeld
 766     unsigned long zeitzaehler=0;            // Ausgabe verlangsamen 500000 etwa 1 Minute
 767    
 768     unsigned char buf[1];
 769     unsigned char merker[6];
 770     unsigned char datensatz[100];
 771     unsigned char datenfeld[100];
 772     unsigned char datenfelder[50][16];
 773     bool printflag;
 774 
 775     // MQTT Vorbereitung
 776     MQTTClient client;
 777     MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
 778     MQTTClient_message pubmsg = MQTTClient_message_initializer;
 779     MQTTClient_deliveryToken token;
 780     int mqttrc;                             // 
 781     char topic[255];                        // zur Aufnahme Werte unterhalb des basetopic
 782     char *basetopic = "Haus/Heizung/Solaranlage/SunGo/";
 783     
 784     // MQTT Cleint Struktur anlegen
 785     if ((mqttrc = MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS){
 786          printf("Failed to create mqttclient, return code %d\n", mqttrc);
 787          exit(EXIT_FAILURE);
 788     }
 789 
 790    // SerCOM Vorbereitung
 791     struct termios oldtio,newtio;
 792     int fd; // FileDescriptor SerCOM
 793     int res; // SerCOM Einlesekontrolle
 794     
 795     // wenn in Kommandozeile die Schnittstelle mitgegeben wird, dann nimm diese sonst versuche default
 796     if (argc > 1)
 797         fd = open(argv[1], O_RDWR | O_NOCTTY );
 798     else
 799         fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
 800     if (fd <0) {
 801         perror(MODEMDEVICE); 
 802         exit(-1); 
 803     }
 804 
 805     // sichere die aktuellen Einstellungen
 806     tcgetattr(fd,&oldtio); 
 807     
 808     // baue die neuen Einstellungen zusammen
 809     bzero(&newtio, sizeof(newtio));
 810     newtio.c_cflag = BAUDRATE |  CS8 | CLOCAL | CREAD;
 811     newtio.c_iflag = IGNPAR | IXON | IXOFF;
 812     newtio.c_oflag = 0;
 813     newtio.c_lflag = 0; 
 814     newtio.c_cc[VTIME]    = 0;   /* inter-character timer unused */
 815     newtio.c_cc[VMIN]     = 1;   /* blocking read until 1 chars received */
 816 
 817     tcflush(fd, TCIFLUSH);
 818     tcsetattr(fd,TCSANOW,&newtio);
 819    
 820     setvbuf(stdout, (char *)NULL, _IONBF, 0);
 821     
 822     // hier sind alle Vorbereitungen (SERCOM, MQTT) abgeschlossen jetzt koennen die Daten des Interfaces eingelesen, aufbereitet und per MQTT gesendet werden
 823     // Die 4 verschiedenen denkbaren Pakete (DPA_1, DPA_2, DPB_1, DPB_2) beginnen alle mit AA 55 55 AA (DEZ: 170 85 85 170)
 824     // wenn diese Folge erkannt wird bestimmen die beiden folgenden Bytes den Typ des Paketes
 825     while (STOP==FALSE) {   // Endlosschleife 
 826  
 827          res = read(fd,buf,1);   
 828   
 829         //sobald ein AA kommt beginne die Beobachtung
 830         if ((buf[0]==170) && (syncstate==5)){
 831             syncstate=0;
 832         }
 833         if ((buf[0]==170) && (syncstate==0)){  // wenn der syncstate 0 (gleich Anfang) und ein AA erkannt wird dann setze sysncstate=1
 834             syncstate=1;
 835             merker[0]=buf[0];
 836         }
 837         if ((buf[0]==85) && (syncstate==1)){    // wenn der syncstate 1 (AA bereits erkannt) und ein 55 erkannt wird dann setze sysncstate=2
 838             syncstate=2;
 839             merker[1]=buf[0];
 840         }
 841         if ((buf[0]==85) && (syncstate==2)){    // wenn der syncstate 2 (AA 55 bereits erkannt) und ein 55 erkannt wird dann setze sysncstate=3
 842             syncstate=3;
 843             merker[2]=buf[0];
 844         }
 845         if ((buf[0]==170) && (syncstate==3)){    // wenn der syncstate 3 (AA 55 55 bereits erkannt) und ein AA erkannt wird dann setze sysncstate=4
 846             syncstate=4;
 847             merker[3]=buf[0];
 848             state=0;
 849         }
 850         // wenn AA 55 55 AA erkannt wurde steht syncstate auf 4 , in merker[0-3] befindet sich die Syncfolge und state ist 0
 851         // wenn das nachfolgende Byte entweder 01 02 oder 03 ist ist alles wie erwartet und kann weitergehen syncstate = 5
 852         if (((buf[0]==1)||(buf[0]==2)||(buf[0]==3)) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==4)){
 853             merker[4]=buf[0];
 854             syncstate=5;
 855         }   
 856         // ab hier werden die 4 Pakete unterschieden DPA_1 0200 (state 20), DPA_2 0100 (state 10), DPB_1 0301 (state 31) und DPB_2 0300 (state 30)
 857  
 858         if ((buf[0]==0) && (merker[4]==1) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){
 859             state=10; // state 10 bereit fuer 0100  Daten fuer das LC-Display
 860             printflag=FALSE;
 861             for(i=0;i<5;i++)merker[i]=0;
 862  
 863         }
 864         if ((buf[0]==0) && (merker[4]==2) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){
 865             state=20; // state 20 bereit fuer 0200 hat keinen (?) Inhalt -> keine Auswertung 
 866             printflag=FALSE;
 867             for(i=0;i<5;i++)merker[i]=0;
 868      
 869         }
 870         if ((buf[0]==0) && (merker[4]==3) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){
 871             state=30; // state 30 bereit fuer 0300 Datensatze
 872             printflag=FALSE;
 873             for(i=0;i<5;i++)merker[i]=0;
 874             dsIndex=0;
 875  
 876         }
 877         if ((buf[0]==1) && (merker[4]==3) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){
 878             state=31; // state 31 bereit fuer 0301 Datenfaelder
 879             printflag=FALSE;
 880             for(i=0;i<5;i++)merker[i]=0;
 881             dfIndex=0;
 882 
 883         }
 884         
 885  
 886         // state 10 und 20 werden nicht ausgewertet        
 887         if ((state==10) && printflag) {
 888 
 889         }
 890         else if ((state==20) && printflag) {
 891  
 892         }
 893         else if ((state==30)  && printflag){
 894  
 895             if(dsIndex<100)datensatz[dsIndex++]=buf[0];
 896         }
 897         else if ((state==31) && printflag) {
 898  
 899             if(dfIndex<100)datenfeld[dfIndex++]=buf[0];
 900         }
 901         else{
 902          //printf("syncstate: %d, state: %d, %X\n\r",syncstate,state,buf[0]);   
 903         }
 904 
 905         printflag=TRUE;
 906  
 907         if (zeitzaehler==10000){
 908             // es wird etwa 3 mal pro Minute eine Auswahl der Datensaetze ausgegeben
 909             // Datum: 18.09.2021
 910             // Message published, return code 0
 911             // Uhrzeit: 12:17
 912             // Message published, return code 0
 913             // Kollektor:  58.6 °C
 914             // Message published, return code 0
 915             // Speicher unten:  49.2 °C
 916             // Message published, return code 0
 917             // Speicher oben:  52.1 °C
 918             // Message published, return code 0
 919             // Rücklaufanhebung T7:  52.0 °C
 920             // Message published, return code 0
 921             // Rücklaufanhebung T8:  28.1 °C
 922             // Message published, return code 0
 923             // Ausgang 1:  60%
 924             // Message published, return code 0
 925             // Ausgang 6: 100%
 926             // Message published, return code 0
 927             // Speicher 2: 15632h
 928             // Message published, return code 0
 929 
 930             conn_opts.keepAliveInterval = 20;
 931             conn_opts.cleansession = 1;
 932             // Baue MQTT Verbindung auf
 933             if ((mqttrc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS){
 934                 printf("Failed to connect, return code %d\n", mqttrc);
 935                 exit(EXIT_FAILURE);
 936             }
 937             //Datum
 938             formatieren(DATUM,datensatz[2],datensatz[3]);
 939             printf("Datum: %s\n",datum); 
 940             strcpy(topic,basetopic);
 941             strcat(topic,"Datum");
 942             pubmsg.payload = datum;
 943             pubmsg.payloadlen = (int)strlen(datum);
 944             pubmsg.qos = QOS;
 945             pubmsg.retained = 0;
 946             if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
 947                 printf("Failed to publish message, return code %d\n", mqttrc);
 948                 exit(EXIT_FAILURE);
 949             }else{
 950                 printf("Message published, return code %d\n", mqttrc); 
 951             }  
 952             //Uhrzeit
 953             formatieren(UHRZEIT,datensatz[4],datensatz[5]);
 954             printf("Uhrzeit: %s\n",uhrzeit);
 955             strcpy(topic,basetopic);            
 956             strcat(topic,"Uhrzeit");            
 957             pubmsg.payload = uhrzeit;
 958             pubmsg.payloadlen = (int)strlen(uhrzeit);
 959             pubmsg.qos = QOS;
 960             pubmsg.retained = 0;
 961             if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
 962                 printf("Failed to publish message, return code %d\n", mqttrc);
 963                 exit(EXIT_FAILURE);
 964             }else{
 965                 printf("Message published, return code %d\n", mqttrc); 
 966             } 
 967             //Kollektor
 968             formatieren(TEMPERATUR,datensatz[6],datensatz[7]);
 969             printf("Kollektor: %s\n",temperatur);
 970             strcpy(topic,basetopic);            
 971             strcat(topic,"Kollektor/Temperatur");
 972             pubmsg.payload = temperatur;
 973             pubmsg.payloadlen = (int)strlen(temperatur);
 974             pubmsg.qos = QOS;
 975             pubmsg.retained = 0;
 976             if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
 977                 printf("Failed to publish message, return code %d\n", mqttrc);
 978                 exit(EXIT_FAILURE);
 979             }else{
 980                 printf("Message published, return code %d\n", mqttrc); 
 981             }
 982              //Speicher unten
 983             formatieren(TEMPERATUR,datensatz[8],datensatz[9]);
 984             printf("Speicher unten: %s\n",temperatur);
 985             strcpy(topic,basetopic);            
 986             strcat(topic,"Speicher/unten/Temperatur");
 987             pubmsg.payload = temperatur;
 988             pubmsg.payloadlen = (int)strlen(temperatur);
 989             pubmsg.qos = QOS;
 990             pubmsg.retained = 0;
 991             if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
 992                 printf("Failed to publish message, return code %d\n", mqttrc);
 993                 exit(EXIT_FAILURE);
 994             }else{
 995                 printf("Message published, return code %d\n", mqttrc); 
 996             }
 997             //Speicher oben
 998             formatieren(TEMPERATUR,datensatz[10],datensatz[11]);
 999             printf("Speicher oben: %s\n",temperatur);
1000             strcpy(topic,basetopic);            
1001             strcat(topic,"Speicher/oben/Temperatur");
1002             pubmsg.payload = temperatur;
1003             pubmsg.payloadlen = (int)strlen(temperatur);
1004             pubmsg.qos = QOS;
1005             pubmsg.retained = 0;
1006             if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
1007                 printf("Failed to publish message, return code %d\n", mqttrc);
1008                 exit(EXIT_FAILURE);
1009             }else{
1010                 printf("Message published, return code %d\n", mqttrc); 
1011             } 
1012             //Rücklaufanhebung T7
1013             formatieren(TEMPERATUR,datensatz[18],datensatz[19]);
1014             printf("Rücklaufanhebung T7: %s\n",temperatur);
1015             strcpy(topic,basetopic);            
1016             strcat(topic,"Rücklaufanhebung/T7/Temperatur");
1017             pubmsg.payload = temperatur;
1018             pubmsg.payloadlen = (int)strlen(temperatur);
1019             pubmsg.qos = QOS;
1020             pubmsg.retained = 0;
1021             if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
1022                 printf("Failed to publish message, return code %d\n", mqttrc);
1023                 exit(EXIT_FAILURE);
1024             }else{
1025                 printf("Message published, return code %d\n", mqttrc); 
1026             }              
1027             //Rücklaufanhebung T8
1028             formatieren(TEMPERATUR,datensatz[20],datensatz[21]);
1029             printf("Rücklaufanhebung T8: %s\n",temperatur);
1030             strcpy(topic,basetopic);            
1031             strcat(topic,"Rücklaufanhebung/T8/Temperatur");
1032             pubmsg.payload = temperatur;
1033             pubmsg.payloadlen = (int)strlen(temperatur);
1034             pubmsg.qos = QOS;
1035             pubmsg.retained = 0;
1036             if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
1037                 printf("Failed to publish message, return code %d\n", mqttrc);
1038                 exit(EXIT_FAILURE);
1039             }else{
1040                 printf("Message published, return code %d\n", mqttrc); 
1041             } 
1042            //Ausgang 1
1043             formatieren(PROZENT,datensatz[32],0);
1044             printf("Ausgang 1: %s\n",prozent);
1045             strcpy(topic,basetopic);            
1046             strcat(topic,"Ausgang/1/Prozent");
1047             pubmsg.payload = prozent;
1048             pubmsg.payloadlen = (int)strlen(prozent);
1049             pubmsg.qos = QOS;
1050             pubmsg.retained = 0;
1051             if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
1052                 printf("Failed to publish message, return code %d\n", mqttrc);
1053                 exit(EXIT_FAILURE);
1054             }else{
1055                 printf("Message published, return code %d\n", mqttrc); 
1056             }  
1057            //Ausgang 6
1058             formatieren(PROZENT,datensatz[37],0);
1059             printf("Ausgang 6: %s\n",prozent);
1060             strcpy(topic,basetopic);            
1061             strcat(topic,"Ausgang/6/Prozent");
1062             pubmsg.payload = prozent;
1063             pubmsg.payloadlen = (int)strlen(prozent);
1064             pubmsg.qos = QOS;
1065             pubmsg.retained = 0;
1066             if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
1067                 printf("Failed to publish message, return code %d\n", mqttrc);
1068                 exit(EXIT_FAILURE);
1069             }else{
1070                 printf("Message published, return code %d\n", mqttrc); 
1071             }  
1072             // Speicherstunden
1073             formatieren(SPEICHER2,datensatz[50],datensatz[51]);
1074             printf("Speicher 2: %s\n",stunden);
1075             strcpy(topic,basetopic);            
1076             strcat(topic,"Speicher/Stunden");
1077             pubmsg.payload = stunden;
1078             pubmsg.payloadlen = (int)strlen(stunden);
1079             pubmsg.qos = QOS;
1080             pubmsg.retained = 0;
1081             if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
1082                 printf("Failed to publish message, return code %d\n", mqttrc);
1083                 exit(EXIT_FAILURE);
1084             }else{
1085                 printf("Message published, return code %d\n", mqttrc); 
1086             }  
1087     /*    printf("Waiting for up to %d seconds for publication of %s\n"
1088                 "on topic %s for client with ClientID: %s\n",
1089                 (int)(TIMEOUT/1000), PAYLOAD, TOPIC, CLIENTID);
1090         rc = MQTTClient_waitForCompletion(client, token, TIMEOUT);
1091         printf("Message with delivery token %d delivered\n", token);
1092     */
1093             if ((mqttrc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS){
1094                 printf("Failed to disconnect, return code %d\n", mqttrc);
1095             }
1096             zeitzaehler=0;
1097         }
1098         zeitzaehler++;
1099         if (zeitzaehler%100000==0)printf("%d\n",zeitzaehler); // Lebenszeichen
1100       
1101     }
1102     
1103     close(fd);                      // schliesze serielle Schnittstelle
1104     
1105     tcsetattr(fd,TCSANOW,&oldtio);  // stelle die alte ComConfig wieder her
1106    
1107     MQTTClient_destroy(&client);    // beende die MQTT Kommunikation
1108     
1109     return EXIT_SUCCESS;
1110 }

Sungoauswertungcurses

Sungoauswertungcurses.c
  1 #include <string.h>
  2 #include <stdlib.h>
  3 #include <stdio.h>
  4 #include <unistd.h>
  5 #include <sys/types.h>
  6 #include <sys/stat.h>
  7 #include <fcntl.h>
  8 #include <termios.h> // termios is the API that is in general recommended for serial I/O in Unix.
  9 #include <curses.h>
 10 
 11 #define BAUDRATE B115200
 12 #define MODEMDEVICE "/dev/ttyS1"
 13 #define _POSIX_SOURCE 1 /* POSIX compliant source */
 14 #define FALSE 0
 15 #define TRUE 1
 16 
 17 volatile int STOP=FALSE;
 18 
 19 char datum[11];
 20 char uhrzeit[7];
 21 char temperatur[25];
 22 char prozent[7];
 23 char fehler[17];
 24 char stunden[8];
 25 char dummy[7];
 26 
 27 
 28 unsigned int hextodec(char hex[10]){
 29   unsigned int decimal=0;
 30   unsigned int length=0;
 31   unsigned int base = 1;
 32   int i=0;
 33   
 34   while(hex[i]!='\0'){
 35     i++;
 36   }
 37   length=i;
 38 
 39     //printf("hextodec %s\n\r",hex);
 40     //printf("length %d\n\r",length);
 41   
 42   for(i = length-1; i >= 0; i--){
 43     //printf("i: %d\n\r",i); 
 44     if (i<0)i=0;
 45       if(hex[i] >= '0' && hex[i] <= '9'){
 46         decimal += ((unsigned char)hex[i] - 48) * base;
 47         base *= 16;
 48       }
 49       else if(hex[i] >= 'A' && hex[i] <= 'F'){
 50         decimal += ((unsigned char)hex[i] - 55) * base;
 51         base *= 16;
 52       }
 53       else if(hex[i] >= 'a' && hex[i] <= 'f'){
 54         decimal += ((unsigned char)hex[i] - 87) * base;
 55         base *= 16;
 56       }
 57   }
 58   //printf("decimal %d\n\r",decimal);
 59   return decimal;
 60 }
 61 
 62 
 63 void datumformatieren(unsigned char lowbyte,unsigned char highbyte){
 64     char data[10]="";
 65     char tmp[3]="";
 66     char datumStr_formatted[]="00.00.2021";
 67     char datumStr[5]="";
 68     unsigned int datumInt;
 69     size_t l;
 70     
 71     sprintf(tmp,"%X",highbyte);
 72     strcpy(data,tmp);
 73     //l=strlen(data);
 74     //printf("data: %s (%d)\n\r",data,l);
 75     
 76     sprintf(tmp,"%X",lowbyte);
 77     strcat(data,tmp);
 78     //l=strlen(data);
 79     //printf("data: %s (%d)\n\r",data,l);  
 80     
 81     //strcpy(data,"0135");
 82     //printf("data: %s\n\r",data);
 83     datumInt=hextodec(data);
 84     //printf("int: %d\n\r",datumInt);
 85     sprintf(datumStr,"%d",datumInt);
 86     if(strlen(datumStr)==3){
 87         datumStr_formatted[0]=datumStr[1];  
 88         datumStr_formatted[1]=datumStr[2]; 
 89         datumStr_formatted[4]=datumStr[0]; 
 90         strcpy(datum,datumStr_formatted);
 91     }
 92     else if(strlen(datumStr)==4){
 93         datumStr_formatted[0]=datumStr[2];  
 94         datumStr_formatted[1]=datumStr[3]; 
 95         datumStr_formatted[3]=datumStr[0]; 
 96         datumStr_formatted[4]=datumStr[1]; 
 97         strcpy(datum,datumStr_formatted);
 98     }   
 99     else{
100         strcpy(datum,"Error!");
101     }
102     return;
103 }
104 
105 
106 void uhrzeitformatieren(unsigned char lowbyte,unsigned char highbyte){
107     char data[10]="";
108     char tmp[3]="";
109     char uhrzeitStr_formatted[]="00:00";
110     unsigned int uhrzeitInt, stunden, minuten;
111     size_t l;
112     
113     sprintf(tmp,"%02X",highbyte);
114     strcpy(data,tmp);
115     //l=strlen(data);
116     //printf("data: %s (%d)\n\r",data,l);
117     
118     sprintf(tmp,"%02X",lowbyte);
119     strcat(data,tmp);
120     //l=strlen(data);
121     //printf("data: %s (%d)\n\r",data,l);  
122     
123     //strcpy(data,"1500");
124     //printf("data: %s\n\r",data);
125     uhrzeitInt=hextodec(data);
126     //printf("int: %d\n\r",uhrzeitInt);
127     stunden=(unsigned int)uhrzeitInt/60;
128     minuten=uhrzeitInt-(stunden*60);
129     if(TRUE){ // hier koennte man die gueltig der stunden und minuten noch testen 
130         sprintf(uhrzeitStr_formatted,"%02d:%02d",stunden,minuten);
131         strcpy(uhrzeit,uhrzeitStr_formatted);
132     }
133     else{
134         strcpy(uhrzeit,"Error!");
135     }
136     return;
137 }
138 
139 void temperaturformatieren(unsigned char lowbyte,unsigned char highbyte){
140     char data[10]="";
141     char tmp[3]="";
142     char temperaturStr_formatted[20]="";
143     unsigned int temperaturInt;
144     float temperaturFloat;
145     size_t l;
146  
147     memset(data,'\0',sizeof(data)); 
148     memset(tmp,'\0',sizeof(tmp)); 
149  
150     
151     sprintf(tmp,"%02X",highbyte);
152     strcpy(data,tmp);
153     //l=strlen(data);
154     //printf("data: %s (%d)\n\r",data,l);
155     
156     sprintf(tmp,"%02X",lowbyte);
157     strcat(data,tmp);
158     //l=strlen(data);
159     //printf("data: %s (%d)\n\r",data,l);  
160     
161 
162     //strcpy(data,"0500");
163     //printf("data: %s\n\r",data);
164     temperaturInt=hextodec(data);
165     //printf("int: %d\n\r",temperaturInt);
166     temperaturFloat=(float)temperaturInt/10.0;
167     
168     if(TRUE){
169         memset(temperaturStr_formatted,'\0',sizeof(temperaturStr_formatted));
170         sprintf(temperaturStr_formatted,"%5.1f °C (%d)     ",temperaturFloat,temperaturInt);
171         strcpy(temperatur,temperaturStr_formatted);
172     }
173     else{
174         strcpy(temperatur,"Error!\0");
175     }
176     return;
177 }
178 
179 
180 void prozentformatieren(unsigned char byte){
181     char data[10]="";
182     char tmp[3]="";
183     char prozentStr_formatted[]="000%";
184     unsigned int prozentInt;
185     size_t l;
186     
187     sprintf(tmp,"%X",byte);
188     strcpy(data,tmp);
189     //l=strlen(data);
190     //printf("data: %s (%d)\n\r",data,l);
191     
192    
193     //strcpy(data,"1500");
194     //printf("data: %s\n\r",data);
195     prozentInt=hextodec(data);
196     //printf("int: %d\n\r",prozentInt);
197     
198     if(TRUE){
199         sprintf(prozentStr_formatted,"%3d%%",prozentInt);
200         strcpy(prozent,prozentStr_formatted);
201     }
202     else{
203         strcpy(prozent,"Error!");
204     }
205     return;
206 }
207 
208 
209 void stundenformatieren(unsigned char lowbyte,unsigned char highbyte){
210     char data[10]="";
211     char tmp[3]="";
212     char stundenStr_formatted[]="000000h";
213     unsigned int stundenInt;
214       
215     sprintf(tmp,"%X",highbyte);
216     strcpy(data,tmp);
217     //l=strlen(data);
218     //printf("data: %s (%d)\n\r",data,l);
219     
220     sprintf(tmp,"%X",lowbyte);
221     strcat(data,tmp);
222     //l=strlen(data);
223     //printf("data: %s (%d)\n\r",data,l);  
224     
225     //strcpy(data,"1500");
226     //printf("data: %s\n\r",data);
227     stundenInt=hextodec(data);
228     //printf("int: %d\n\r",temperaturInt);
229      
230     if(TRUE){
231         sprintf(stundenStr_formatted,"%dh",stundenInt);
232         strcpy(stunden,stundenStr_formatted);
233     }
234     else{
235         strcpy(stunden,"Error!");
236     }
237     return;
238 }
239 
240 void fehlerformatieren(unsigned char byte1,unsigned char byte2,unsigned char byte3,unsigned char byte4,unsigned char byte5,unsigned char byte6,unsigned char byte7,unsigned char byte8){
241     char data[10]="";
242     char tmp[3]="";
243     char fehlerStr_formatted[9];
244     unsigned int fehlerInt;
245 
246     fehlerInt=12345;
247     
248     if(TRUE){
249         sprintf(fehlerStr_formatted,"%d",fehlerInt);
250         strcpy(fehler,fehlerStr_formatted);
251     }
252     else{
253         strcpy(fehler,"Error!");
254     }
255     return;
256 }
257 
258 
259 void dummyformatieren(unsigned char lowbyte,unsigned char highbyte){
260     char data[10]="";
261     char tmp[3]="";
262      
263     sprintf(tmp,"%X",highbyte);
264     strcpy(data,tmp);
265     //l=strlen(data);
266     //printf("data: %s (%d)\n\r",data,l);
267     
268     sprintf(tmp,"%X",lowbyte);
269     strcat(data,tmp);
270     //l=strlen(data);
271     //printf("data: %s (%d)\n\r",data,l);  
272     
273     if(TRUE){
274          strcpy(dummy,data);
275     }
276     else{
277         strcpy(dummy,"Error!");
278     }
279     return;
280 }
281 
282 int main(int argc, char **argv)
283 {
284    
285     struct termios oldtio,newtio;
286     
287     int fd;
288     int c;
289     int res;
290     int i,k,l;
291     unsigned int x,y,z,t1,t2,t3,dsIndex, dfIndex, dfX, dfY, sort1,sort2, stelle, zeilenproblock;
292     unsigned int state=0, syncstate=0;
293    
294     unsigned char buf[1];
295     unsigned char merker[6];
296     unsigned char datensatz[200];
297     unsigned char datenfeld[100];
298     unsigned char datenfelder[50][16];
299     char data[10]="";
300     char tmp[3]="";
301     bool printflag;
302     
303     memset(temperatur, '\0', sizeof(temperatur));
304     
305 
306     // wenn in Kommandozeile die Schnittstelle mitgegeben wird, dann nim diese sonst veruche default
307     if (argc > 1)
308         fd = open(argv[1], O_RDWR | O_NOCTTY );
309     else
310         fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
311     if (fd <0) {
312         perror(MODEMDEVICE); 
313         exit(-1); 
314     }
315 
316     // sichere die aktuellen Einstellungen
317     tcgetattr(fd,&oldtio); 
318     
319     // baue die neuen Einstellungen zusammen
320     bzero(&newtio, sizeof(newtio));
321     newtio.c_cflag = BAUDRATE |  CS8 | CLOCAL | CREAD;
322     newtio.c_iflag = IGNPAR | IXON | IXOFF;
323     newtio.c_oflag = 0;
324     newtio.c_lflag = 0; 
325     newtio.c_cc[VTIME]    = 0;   /* inter-character timer unused */
326     newtio.c_cc[VMIN]     = 5;   /* blocking read until 5 chars received */
327 
328     tcflush(fd, TCIFLUSH);
329     tcsetattr(fd,TCSANOW,&newtio);
330    
331     setvbuf(stdout, (char *)NULL, _IONBF, 0);
332     
333     initscr();
334     getmaxyx(stdscr,x,y);
335     printf("X:%d/Y:%d\n",x,y);
336     while (STOP==FALSE) {       /* loop for input */
337         res = read(fd,buf,1);   /* returns after 5 chars have been input */
338         //printf("A: syncstate: %d, state: %d, %X\n\r",syncstate,state,buf[0]); 
339  
340         //sobald ein AA kommt beginne die Beobachtung
341         if ((buf[0]==170) && (syncstate==5)){
342             syncstate=0;
343         }
344         if ((buf[0]==170) && (syncstate==0)){
345             syncstate=1;
346             merker[0]=buf[0];
347         }
348         if ((buf[0]==85) && (syncstate==1)){
349             syncstate=2;
350             merker[1]=buf[0];
351         }
352         if ((buf[0]==85) && (syncstate==2)){
353             syncstate=3;
354             merker[2]=buf[0];
355         }
356         if ((buf[0]==170) && (syncstate==3)){
357             syncstate=4;
358             merker[3]=buf[0];
359             state=0;
360         }
361         if (((buf[0]==1)||(buf[0]==2)||(buf[0]==3)) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==4)){
362             merker[4]=buf[0];
363             syncstate=5;
364         }   
365  
366  
367         if ((buf[0]==0) && (merker[4]==1) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){
368             state=10; // state 10 bereit fuer 0100
369             printflag=FALSE;
370             for(i=0;i<5;i++)merker[i]=0;
371             x=1;
372             y=8;
373             stelle=0;
374         }
375         if ((buf[0]==0) && (merker[4]==2) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){
376             state=20; // state 10 bereit fuer 0100
377             printflag=FALSE;
378             for(i=0;i<5;i++)merker[i]=0;
379             x=2;
380             y=8;  
381             stelle=0;            
382         }
383         if ((buf[0]==0) && (merker[4]==3) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){
384             state=30; // state 10 bereit fuer 0100
385             printflag=FALSE;
386             for(i=0;i<5;i++)merker[i]=0;
387             dsIndex=0;
388             x=3;
389             y=8;     
390             stelle=0;
391         }
392         if ((buf[0]==1) && (merker[4]==3) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){
393             state=31; // state 10 bereit fuer 0100
394             printflag=FALSE;
395             for(i=0;i<5;i++)merker[i]=0;
396             dfIndex=0;
397             x=4;
398             y=8;
399             stelle=0;
400         }
401         
402         zeilenproblock=3;
403                 
404         if ((state==10) && printflag) {
405             z=(x-1)*zeilenproblock+x;
406             mvprintw(z,1,"0100:");
407             mvaddch(z,y,buf[0]);
408             mvprintw(z+1,y,"%02X ",buf[0]);
409             mvprintw(z+2,y,"%d ",stelle);
410             y+=3;
411             stelle++;
412         }
413         else if ((state==20) && printflag) {
414             z=(x-1)*zeilenproblock+x;
415             mvprintw(z,1,"0200:");
416             mvaddch(z,y,buf[0]);
417             mvprintw(z+1,y,"%02X ",buf[0]);
418             mvprintw(z+2,y,"%d ",stelle);
419             y+=3;
420             stelle++;
421         }
422         else if ((state==30)  && printflag){
423             z=(x-1)*zeilenproblock+x;
424             mvprintw(z,1,"0300:");
425             mvaddch(z,y,buf[0]);
426             mvprintw(z+1,y,"%02X ",buf[0]);            
427             mvprintw(z+2,y,"%d ",stelle);
428             y+=3;
429             stelle++;
430             if(dsIndex<100)datensatz[dsIndex++]=buf[0];
431         }
432         else if ((state==31) && printflag) {
433             z=(x-1)*zeilenproblock+x;            
434             mvprintw(z,1,"0301:");
435             mvaddch(z,y,buf[0]);
436             mvprintw(z+1,y,"%02X ",buf[0]);            
437             mvprintw(z+2,y,"%d ",stelle);
438             y+=3;
439             stelle++;
440             if(dfIndex<100)datenfeld[dfIndex++]=buf[0];
441         }
442         else{
443          //printf("syncstate: %d, state: %d, %X\n\r",syncstate,state,buf[0]);   
444         }
445         //mvprintw(5,1,"Test");
446         printflag=TRUE;
447         refresh();
448         //printf("E: syncstate: %d, state: %d, %X\n\r",syncstate,state,buf[0]); 
449         //if (buf[0]=='z') STOP=TRUE;
450         //x max = 4
451         z=20;
452         t1=35;
453         t2=t1+30;
454         sort1=0;
455         mvprintw(z+sort1,1,"Datum: (2,3)");
456         datumformatieren(datensatz[2],datensatz[3]);
457         //printf("datum: %s",datum);
458         mvprintw(z+sort1,t1,datum);
459         mvprintw(z+sort1,t2,"%02X %02X",datensatz[2],datensatz[3]);  
460         sort1++;
461         mvprintw(z+sort1,1,"Uhrzeit: (4,5)");
462         uhrzeitformatieren(datensatz[4],datensatz[5]);
463         //printf("uhrzeit: %s",uhrzeit);
464         mvprintw(z+sort1,t1,uhrzeit);  
465         mvprintw(z+sort1,t2,"%02X %02X",datensatz[4],datensatz[5]);  
466         sort1++;
467         mvprintw(z+sort1,1,"Kollektor: (6,7)");
468         temperaturformatieren(datensatz[6],datensatz[7]);
469         //printf("temperatur: %s",temperatur);
470         mvprintw(z+sort1,t1,"%s",temperatur); 
471         mvprintw(z+sort1,t2,"%02X %02X",datensatz[6],datensatz[7]); 
472         sort1++;
473         mvprintw(z+sort1,1,"Speicher unten: (8,9)");
474         temperaturformatieren(datensatz[8],datensatz[9]);
475         //printf("temperatur: %s",temperatur);
476         mvprintw(z+sort1,t1,"%s",temperatur);
477         mvprintw(z+sort1,t2,"%02X %02X",datensatz[8],datensatz[9]); 
478         sort1++;
479         mvprintw(z+sort1,1,"Speicher oben: (10,11)");
480         temperaturformatieren(datensatz[10],datensatz[11]);
481         //printf("temperatur: %s",temperatur);
482         mvprintw(z+sort1,t1,"%s",temperatur); 
483         mvprintw(z+sort1,t2,"%02X %02X",datensatz[10],datensatz[11]); 
484         sort1++;
485         mvprintw(z+sort1,1,"Thermostat: (12,13)");
486         temperaturformatieren(datensatz[12],datensatz[13]);
487         //printf("temperatur: %s",temperatur);
488         mvprintw(z+sort1,t1,"%s",temperatur);  
489         mvprintw(z+sort1,t2,"%02X %02X",datensatz[12],datensatz[13]); 
490         sort1++;
491         mvprintw(z+sort1,1,"Poolschutz: (14,15)");
492         temperaturformatieren(datensatz[14],datensatz[15]);
493         //printf("temperatur: %s",temperatur);
494         mvprintw(z+sort1,t1,"%s",temperatur);
495         mvprintw(z+sort1,t2,"%02X %02X",datensatz[14],datensatz[15]); 
496         sort1++;
497         mvprintw(z+sort1,1,"Ertrag: (16,17)");
498         temperaturformatieren(datensatz[16],datensatz[17]);
499         //printf("temperatur: %s",temperatur);
500         mvprintw(z+sort1,t1,"%s",temperatur); 
501         mvprintw(z+sort1,t2,"%02X %02X",datensatz[16],datensatz[17]); 
502         sort1++;
503         mvprintw(z+sort1,1,"Ruecklaufanhebung T7: (18,19)");
504         temperaturformatieren(datensatz[18],datensatz[19]);
505         //printf("temperatur: %s",temperatur);
506         mvprintw(z+sort1,t1,"%s",temperatur); 
507         mvprintw(z+sort1,t2,"%02X %02X",datensatz[18],datensatz[19]); 
508         sort1++;
509         mvprintw(z+sort1,1,"Ruecklaufanhebung T8: (20,21)");
510         temperaturformatieren(datensatz[20],datensatz[21]);
511         //printf("temperatur: %s",temperatur);
512         mvprintw(z+sort1,t1,"%s",temperatur); 
513         mvprintw(z+sort1,t2,"%02X %02X",datensatz[20],datensatz[21]); 
514         sort1++;
515         mvprintw(z+sort1,1,"T: (22,23)");
516         temperaturformatieren(datensatz[22],datensatz[23]);
517         //printf("temperatur: %s",temperatur);
518         mvprintw(z+sort1,t1,"%s",temperatur); 
519         mvprintw(z+sort1,t2,"%02X %02X",datensatz[22],datensatz[23]); 
520         sort1++;
521         mvprintw(z+sort1,1,"Dummy: (24,25)");
522         dummyformatieren(datensatz[24],datensatz[25]);
523         //printf("dummy: %s",dummy);
524         mvprintw(z+sort1,t1,dummy);
525         mvprintw(z+sort1,t2,"%02X %02X",datensatz[24],datensatz[25]);         
526         sort1++;
527         mvprintw(z+sort1,1,"Strahlung: (26,27)");
528         temperaturformatieren(datensatz[26],datensatz[27]);
529         //printf("temperatur: %s",temperatur);
530         mvprintw(z+sort1,t1,temperatur);
531         mvprintw(z+sort1,t2,"%02X %02X",datensatz[26],datensatz[27]); 
532         sort1++;
533         mvprintw(z+sort1,1,"Dummy: (28,29)");
534         dummyformatieren(datensatz[28],datensatz[29]);
535          //printf("dummy: %s",dummy);
536         mvprintw(z+sort1,t1,dummy);  
537         mvprintw(z+sort1,t2,"%02X %02X",datensatz[28],datensatz[29]); 
538         sort1++;
539         mvprintw(z+sort1,1,"Dummy: (30,31)");
540         temperaturformatieren(datensatz[30],datensatz[31]);
541         //printf("dummy: %s",dummy);
542         mvprintw(z+sort1,t1,dummy);   
543         mvprintw(z+sort1,t2,"%02X %02X",datensatz[30],datensatz[31]); 
544         sort1++;
545         mvprintw(z+sort1,1,"Ausgang 1: (32)");
546         prozentformatieren(datensatz[32]);
547         //printf("prozent: %s",prozent);
548         mvprintw(z+sort1,t1,prozent);  
549         mvprintw(z+sort1,t2,"%02X",datensatz[32]); 
550         sort1++;
551         mvprintw(z+sort1,1,"Ausgang 2: (33)");
552         prozentformatieren(datensatz[33]);
553         //printf("prozent: %s",prozent);
554         mvprintw(z+sort1,t1,prozent);  
555         mvprintw(z+sort1,t2,"%02X",datensatz[33]);
556         sort1++;
557         mvprintw(z+sort1,1,"Ausgang 3: (34)");
558         prozentformatieren(datensatz[34]);
559         //printf("prozent: %s",prozent);
560         mvprintw(z+sort1,t1,prozent);   
561         mvprintw(z+sort1,t2,"%02X",datensatz[34]);
562         sort1++;
563         mvprintw(z+sort1,1,"Ausgang 4: (35)");
564         prozentformatieren(datensatz[35]);
565         //printf("prozent: %s",prozent);
566         mvprintw(z+sort1,t1,prozent);
567         mvprintw(z+sort1,t2,"%02X",datensatz[35]);
568         sort1++;
569         mvprintw(z+sort1,1,"Ausgang 5: (36)");
570         prozentformatieren(datensatz[36]);
571         //printf("prozent: %s",prozent);
572         mvprintw(z+sort1,t1,prozent);
573         mvprintw(z+sort1,t2,"%02X",datensatz[36]);
574         sort1++;
575         mvprintw(z+sort1,1,"Ausgang 6: (37)");
576         prozentformatieren(datensatz[37]);
577         //printf("prozent: %s",prozent);
578         mvprintw(z+sort1,t1,prozent);
579         mvprintw(z+sort1,t2,"%02X",datensatz[37]);
580         sort1++;
581         mvprintw(z+sort1,1,"Fehler: (38-45)");
582         fehlerformatieren(datensatz[38],datensatz[39],datensatz[40],datensatz[41],datensatz[42],datensatz[43],datensatz[44],datensatz[45]);
583         //printf("fehler: %s",fehler);
584         mvprintw(z+sort1,t1,fehler); 
585         mvprintw(z+sort1,t2,"%02X %02X %02X %02X %02X %02X %02X %02X",datensatz[38],datensatz[39],datensatz[40],datensatz[41],datensatz[42],datensatz[43],datensatz[44],datensatz[45]);
586         sort1++;
587         mvprintw(z+sort1,1,"Speicher 1: (46,47)");
588         temperaturformatieren(datensatz[46],datensatz[47]);
589         //printf("temperatur: %s",temperatur);
590         mvprintw(z+sort1,t1,temperatur);
591         mvprintw(z+sort1,t2,"%02X %02X",datensatz[46],datensatz[47]); 
592         sort1++;
593         mvprintw(z+sort1,1,"Dummy: (48,49)");
594         dummyformatieren(datensatz[48],datensatz[49]);
595         //printf("dummy: %s",dummy);
596         mvprintw(z+sort1,t1,dummy);
597         mvprintw(z+sort1,t2,"%02X %02X",datensatz[48],datensatz[49]); 
598         sort1++;
599         mvprintw(z+sort1,1,"Speicher 2: (50,51)");
600         stundenformatieren(datensatz[50],datensatz[51]);
601         //printf("stunden: %s",stunden);
602         mvprintw(z+sort1,t1,stunden);
603         mvprintw(z+sort1,t2,"%02X %02X",datensatz[50],datensatz[51]); 
604         sort1++;
605         mvprintw(z+sort1,1,"Dummy: (52,53)");
606         dummyformatieren(datensatz[52],datensatz[53]);
607         //printf("dummy: %s",dummy);
608         mvprintw(z+sort1,t1,dummy); 
609         mvprintw(z+sort1,t2,"%02X %02X",datensatz[52],datensatz[53]); 
610         sort1++;
611         mvprintw(z+sort1,1,"Dummy: (54,55)");
612         dummyformatieren(datensatz[54],datensatz[55]);
613         //printf("dummy: %s",dummy);
614         mvprintw(z+sort1,t1,dummy); 
615         mvprintw(z+sort1,t2,"%02X %02X",datensatz[54],datensatz[55]); 
616         sort1++;
617         mvprintw(z+sort1,1,"Funktion 1 aktiv: (56,57)");
618         dummyformatieren(datensatz[56],datensatz[57]);
619         //printf("dummy: %s",dummy);
620         mvprintw(z+sort1,t1,dummy); 
621         mvprintw(z+sort1,t2,"%02X %02X",datensatz[56],datensatz[57]); 
622         sort1++;
623         mvprintw(z+sort1,1,"Funktion 2 aktiv: (58,59)");
624         dummyformatieren(datensatz[58],datensatz[59]);
625         //printf("dummy: %s",dummy);
626         mvprintw(z+sort1,t1,dummy);
627         mvprintw(z+sort1,t2,"%02X %02X",datensatz[58],datensatz[59]); 
628         sort1++;
629         mvprintw(z+sort1,1,"Volumenstrom: (60,61)");
630         dummyformatieren(datensatz[60],datensatz[61]);
631         //printf("dummy: %s",dummy);
632         mvprintw(z+sort1,t1,dummy);
633         mvprintw(z+sort1,t2,"%02X %02X",datensatz[60],datensatz[61]); 
634         sort1++;
635         mvprintw(z+sort1,1,"Dummy: (62,63)");
636         dummyformatieren(datensatz[62],datensatz[63]);
637         //printf("dummy: %s",dummy);
638         mvprintw(z+sort1,t1,dummy); 
639         mvprintw(z+sort1,t2,"%02X %02X",datensatz[62],datensatz[63]); 
640         sort1++;
641         mvprintw(z+sort1,1,"Dummy: (64,65)");
642         dummyformatieren(datensatz[64],datensatz[65]);
643         //printf("dummy: %s",dummy);
644         mvprintw(z+sort1,t1,dummy);
645         mvprintw(z+sort1,t2,"%02X %02X",datensatz[64],datensatz[65]); 
646         
647         t3=t2+20;
648         sort2=0;
649         
650         i=0;
651         mvprintw(z+sort2,t3,"%02X ",datenfeld[i++]);   
652         mvprintw(z+sort2,t3+3,"%02X ",datenfeld[i++]);
653         mvprintw(z+sort2,t3+6,"%02X ",datenfeld[i++]); 
654         for(k=0;k<32;k++){
655             sprintf(tmp,"%X",datenfeld[i+(k*16)]);
656             strcpy(data,tmp);
657             sort2=hextodec(data)*2;
658             if (sort2>62) sort2=64;
659             for(l=0;l<16;l++){
660                 mvprintw(z+sort2,t3+(l*3),"%02X ",datenfeld[i+(k*16)+l]);  
661                 if (datenfeld[i+(k*16)+l]!=0){ mvprintw(z+sort2+1,t3+(l*3),"%c ",datenfeld[i+(k*16)+l]);  }
662                 else { mvprintw(z+sort2+1,t3+(l*3)," "); }
663             }
664         }
665         
666     }
667     endwin();
668     
669     close(fd);
670     
671     tcsetattr(fd,TCSANOW,&oldtio);
672     
673     return EXIT_SUCCESS;
674 }

Sungoserialcapture

Sungoserialcapture.c
  1 #include <string.h>
  2 #include <stdlib.h>
  3 #include <stdio.h>
  4 #include <unistd.h>
  5 #include <sys/types.h>
  6 #include <sys/stat.h>
  7 #include <fcntl.h>
  8 #include <termios.h> // termios is the API that is in general recommended for serial I/O in Unix.
  9 #include <curses.h>
 10 
 11 #define BAUDRATE B115200
 12 #define MODEMDEVICE "/dev/ttyS1"
 13 #define _POSIX_SOURCE 1 /* POSIX compliant source */
 14 #define FALSE 0
 15 #define TRUE 1
 16 
 17 volatile int STOP=FALSE;
 18 
 19 char datum[11];
 20 char uhrzeit[7];
 21 char temperatur[8];
 22 char prozent[7];
 23 char fehler[17];
 24 char stunden[8];
 25 char dummy[7];
 26 
 27 unsigned int hextodec(char hex[10]){
 28   unsigned int decimal=0;
 29   unsigned int length=0;
 30   unsigned int base = 1;
 31   int i=0;
 32   
 33   while(hex[i]!='\0'){
 34     i++;
 35   }
 36   length=i;
 37 
 38   //printf("hextodec %s\n\r",hex);
 39   //printf("length %d\n\r",length);
 40   
 41   for(i = length-1; i >= 0; i--){
 42     //printf("i: %d\n\r",i); 
 43     if (i<0)i=0;
 44       if(hex[i] >= '0' && hex[i] <= '9'){
 45         decimal += ((unsigned char)hex[i] - 48) * base;
 46         base *= 16;
 47       }
 48       else if(hex[i] >= 'A' && hex[i] <= 'F'){
 49         decimal += ((unsigned char)hex[i] - 55) * base;
 50         base *= 16;
 51       }
 52       else if(hex[i] >= 'a' && hex[i] <= 'f'){
 53         decimal += ((unsigned char)hex[i] - 87) * base;
 54         base *= 16;
 55       }
 56   }
 57   //printf("decimal %d\n\r",decimal);
 58   return decimal;
 59 }
 60 
 61 
 62 void datumformatieren(unsigned char lowbyte,unsigned char highbyte){
 63     char data[10]="";
 64     char tmp[3]="";
 65     char datumStr_formatted[]="00.00.2021";
 66     char datumStr[5]="";
 67     unsigned int datumInt;
 68     size_t l;
 69     
 70     sprintf(tmp,"%X",highbyte);
 71     strcpy(data,tmp);
 72     //l=strlen(data);
 73     //printf("data: %s (%d)\n\r",data,l);
 74     
 75     sprintf(tmp,"%X",lowbyte);
 76     strcat(data,tmp);
 77     //l=strlen(data);
 78     //printf("data: %s (%d)\n\r",data,l);  
 79     
 80     //strcpy(data,"0135");
 81     //printf("data: %s\n\r",data);
 82     datumInt=hextodec(data);
 83     //printf("int: %d\n\r",datumInt);
 84     sprintf(datumStr,"%d",datumInt);
 85     if(strlen(datumStr)==3){
 86         datumStr_formatted[0]=datumStr[1];  
 87         datumStr_formatted[1]=datumStr[2]; 
 88         datumStr_formatted[4]=datumStr[0]; 
 89         strcpy(datum,datumStr_formatted);
 90     }
 91     else if(strlen(datumStr)==4){
 92         datumStr_formatted[0]=datumStr[2];  
 93         datumStr_formatted[1]=datumStr[3]; 
 94         datumStr_formatted[3]=datumStr[0]; 
 95         datumStr_formatted[4]=datumStr[1]; 
 96         strcpy(datum,datumStr_formatted);
 97     }   
 98     else{
 99         strcpy(datum,"Error!");
100     }
101     return;
102 }
103 
104 
105 void uhrzeitformatieren(unsigned char lowbyte,unsigned char highbyte){
106     char data[10]="";
107     char tmp[3]="";
108     char uhrzeitStr_formatted[]="00:00";
109     unsigned int uhrzeitInt, stunden, minuten;
110     size_t l;
111     
112     sprintf(tmp,"%X",highbyte);
113     strcpy(data,tmp);
114     //l=strlen(data);
115     //printf("data: %s (%d)\n\r",data,l);
116     
117     sprintf(tmp,"%X",lowbyte);
118     strcat(data,tmp);
119     //l=strlen(data);
120     //printf("data: %s (%d)\n\r",data,l);  
121     
122     //strcpy(data,"1500");
123     //printf("data: %s\n\r",data);
124     uhrzeitInt=hextodec(data);
125     //printf("int: %d\n\r",uhrzeitInt);
126     stunden=(unsigned int)uhrzeitInt/60;
127     minuten=uhrzeitInt-(stunden*60);
128     if(TRUE){ // hier koennte man die gueltig der stunden und minuten noch testen 
129         sprintf(uhrzeitStr_formatted,"%d:%d",stunden,minuten);
130         strcpy(uhrzeit,uhrzeitStr_formatted);
131     }
132     else{
133         strcpy(uhrzeit,"Error!");
134     }
135     return;
136 }
137 
138 void temperaturformatieren(unsigned char lowbyte,unsigned char highbyte){
139     char data[10]="";
140     char tmp[3]="";
141     char temperaturStr_formatted[]="000.0°C";
142     unsigned int temperaturInt;
143     float temperaturFloat;
144     size_t l;
145     
146     sprintf(tmp,"%X",highbyte);
147     strcpy(data,tmp);
148     //l=strlen(data);
149     //printf("data: %s (%d)\n\r",data,l);
150     
151     sprintf(tmp,"%X",lowbyte);
152     strcat(data,tmp);
153     //l=strlen(data);
154     //printf("data: %s (%d)\n\r",data,l);  
155     
156     //strcpy(data,"1500");
157     //printf("data: %s\n\r",data);
158     temperaturInt=hextodec(data);
159     //printf("int: %d\n\r",temperaturInt);
160     temperaturFloat=(float)temperaturInt/10.0;
161     
162     if(TRUE){
163         sprintf(temperaturStr_formatted,"%.1f°C",temperaturFloat);
164         strcpy(temperatur,temperaturStr_formatted);
165     }
166     else{
167         strcpy(temperatur,"Error!");
168     }
169     return;
170 }
171 
172 
173 void prozentformatieren(unsigned char byte){
174     char data[10]="";
175     char tmp[3]="";
176     char prozentStr_formatted[]="000%";
177     unsigned int prozentInt;
178     size_t l;
179     
180     sprintf(tmp,"%X",byte);
181     strcpy(data,tmp);
182     //l=strlen(data);
183     //printf("data: %s (%d)\n\r",data,l);
184     
185    
186     //strcpy(data,"1500");
187     //printf("data: %s\n\r",data);
188     prozentInt=hextodec(data);
189     //printf("int: %d\n\r",prozentInt);
190     
191     if(TRUE){
192         sprintf(prozentStr_formatted,"%d%%",prozentInt);
193         strcpy(prozent,prozentStr_formatted);
194     }
195     else{
196         strcpy(prozent,"Error!");
197     }
198     return;
199 }
200 
201 
202 void stundenformatieren(unsigned char lowbyte,unsigned char highbyte){
203     char data[10]="";
204     char tmp[3]="";
205     char stundenStr_formatted[]="000000h";
206     unsigned int stundenInt;
207       
208     sprintf(tmp,"%X",highbyte);
209     strcpy(data,tmp);
210     //l=strlen(data);
211     //printf("data: %s (%d)\n\r",data,l);
212     
213     sprintf(tmp,"%X",lowbyte);
214     strcat(data,tmp);
215     //l=strlen(data);
216     //printf("data: %s (%d)\n\r",data,l);  
217     
218     //strcpy(data,"1500");
219     //printf("data: %s\n\r",data);
220     stundenInt=hextodec(data);
221     //printf("int: %d\n\r",temperaturInt);
222      
223     if(TRUE){
224         sprintf(stundenStr_formatted,"%dh",stundenInt);
225         strcpy(stunden,stundenStr_formatted);
226     }
227     else{
228         strcpy(stunden,"Error!");
229     }
230     return;
231 }
232 
233 void fehlerformatieren(unsigned char byte1,unsigned char byte2,unsigned char byte3,unsigned char byte4,unsigned char byte5,unsigned char byte6,unsigned char byte7,unsigned char byte8){
234     char data[10]="";
235     char tmp[3]="";
236     char fehlerStr_formatted[9];
237     unsigned int fehlerInt;
238 
239     fehlerInt=12345;
240     
241     if(TRUE){
242         sprintf(fehlerStr_formatted,"%d",fehlerInt);
243         strcpy(fehler,fehlerStr_formatted);
244     }
245     else{
246         strcpy(fehler,"Error!");
247     }
248     return;
249 }
250 
251 
252 void dummyformatieren(unsigned char lowbyte,unsigned char highbyte){
253     char data[10]="";
254     char tmp[3]="";
255      
256     sprintf(tmp,"%X",highbyte);
257     strcpy(data,tmp);
258     //l=strlen(data);
259     //printf("data: %s (%d)\n\r",data,l);
260     
261     sprintf(tmp,"%X",lowbyte);
262     strcat(data,tmp);
263     //l=strlen(data);
264     //printf("data: %s (%d)\n\r",data,l);  
265     
266     if(TRUE){
267          strcpy(dummy,data);
268     }
269     else{
270         strcpy(dummy,"Error!");
271     }
272     return;
273 }
274 
275 int main(int argc, char **argv)
276 {
277    FILE *fp;
278    struct termios oldtio,newtio;
279     
280     int fd;
281     int c;
282     int res;
283     int i,k,l;
284     unsigned int x,y,z,t1,t2,dsIndex, dfIndex, dfX, dfY, sort1,sort2, stelle, zeilenproblock;
285     unsigned int state=0, syncstate=0;
286    
287     unsigned char buf[1];
288     unsigned char merker[6];
289     unsigned char datensatz[100];
290     unsigned char datenfeld[100];
291     unsigned char datenfelder[50][16];
292     char data[10]="";
293     char tmp[3]="";
294     bool printflag;
295 
296     // wenn in Kommandozeile die Schnittstelle mitgegeben wird, dann nimm diese sonst veruche default
297     if (argc > 1)
298         fd = open(argv[1], O_RDWR | O_NOCTTY );
299     else
300         fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
301     if (fd <0) {
302         perror(MODEMDEVICE); 
303         exit(-1); 
304     }
305 
306     // sichere die aktuellen Einstellungen
307     tcgetattr(fd,&oldtio); 
308     
309     // baue die neuen Einstellungen zusammen
310     bzero(&newtio, sizeof(newtio));
311     newtio.c_cflag = BAUDRATE |  CS8 | CLOCAL | CREAD;
312     newtio.c_iflag = IGNPAR | IXON | IXOFF;
313     newtio.c_oflag = 0;
314     newtio.c_lflag = 0; 
315     newtio.c_cc[VTIME]    = 0;   /* inter-character timer unused */
316     newtio.c_cc[VMIN]     = 5;   /* blocking read until 5 chars received */
317 
318     tcflush(fd, TCIFLUSH);
319     tcsetattr(fd,TCSANOW,&newtio);
320    
321     setvbuf(stdout, (char *)NULL, _IONBF, 0);
322 
323     fp=fopen("sungocapture.bin","w");
324     
325     if (fp == NULL)
326       return 0;
327     
328     while (STOP==FALSE) {       /* loop for input */
329         res = read(fd,buf,1);   /* returns after 5 chars have been input */
330         //printf("A: syncstate: %d, state: %d, %X\n\r",syncstate,state,buf[0]); 
331  
332         fputc(res,fp);
333         
334     }
335     
336     fclose(fp);
337     
338     close(fd);
339     
340     tcsetattr(fd,TCSANOW,&oldtio);
341     
342     return EXIT_SUCCESS;
343 }