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

Dieses Programm liest die Daten des Interfaces ueber die USB-Schnittstelle ein und uebergibt sie an die Console und den MQTT-Server.

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 }

Sungoauswertungcurses

Dieses Programm dient erst mal nur dem Einlesen und Interpretieren der Daten vom Interface. Sie werden nach der Aufbereitung geordnet und auf der Console mittels curses ausgegeben. In diesem Programm sind noch die alten Varianten der Konvertierungsfunktionen vorhanden. Dies ist zwar nicht elegant, aber es funktioniert.

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

Diese Programm liest die Interfacedaten und schreibt die Daten ohne Auswertung zur weiteren Bearbeitung in ein Datei. Auch in diesem Programm sind noch die alten Varianten der Konvertierungsfunktionen vorhanden. Dies ist zwar nicht elegant, aber es funktioniert.

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 }