Sungo SXL MQTT Anbindung: Unterschied zwischen den Versionen
Zeile 61: | Zeile 61: | ||
− | volatile int STOP=FALSE; // braucht man eigentlich nicht | + | 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 |
+ | // solange das nicht realisiert ist laeuft die "main-Schleife" endlos. | ||
Zeile 147: | Zeile 148: | ||
switch(typ) { | switch(typ) { | ||
− | + | case DUMMY: if(TRUE){ | |
strcpy(dummy,data); | strcpy(dummy,data); | ||
} | } | ||
Zeile 173: | Zeile 174: | ||
} | } | ||
break; | break; | ||
− | + | case UHRZEIT: dataStunden=(unsigned int)dataInteger/60; | |
dataMinuten=dataInteger-(dataStunden*60); | dataMinuten=dataInteger-(dataStunden*60); | ||
if(TRUE){ // hier koennte man die gueltig der stunden und minuten noch testen | if(TRUE){ // hier koennte man die gueltig der stunden und minuten noch testen | ||
Zeile 217: | Zeile 218: | ||
} | } | ||
break; | break; | ||
− | + | default: printf("Type Error (unknown)\n"); break; | |
} | } | ||
Zeile 224: | Zeile 225: | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
− | { int i; // Schleifenzaehler allgemein | + | { int i; // Schleifenzaehler allgemein |
− | unsigned int state=0, syncstate=0; | + | unsigned int state=0, syncstate=0; // state 10,20,30 oder 31 entsprechend 0100, 0200, 0300, 0301 |
− | unsigned int dsIndex, dfIndex; | + | unsigned int dsIndex, dfIndex; // Zeiger auf Datensatz und Datenfeld |
− | unsigned long zeitzaehler=0; | + | unsigned long zeitzaehler=0; // Ausgabe verlangsamen 500000 etwa 1 Minute |
unsigned char buf[1]; | unsigned char buf[1]; | ||
Zeile 241: | Zeile 242: | ||
MQTTClient_message pubmsg = MQTTClient_message_initializer; | MQTTClient_message pubmsg = MQTTClient_message_initializer; | ||
MQTTClient_deliveryToken token; | MQTTClient_deliveryToken token; | ||
− | int mqttrc; | + | int mqttrc; // |
− | char topic[255]; // zur Aufnahme Werte unterhalb des basetopic | + | char topic[255]; // zur Aufnahme Werte unterhalb des basetopic |
char *basetopic = "Haus/Heizung/Solaranlage/SunGo/"; | char *basetopic = "Haus/Heizung/Solaranlage/SunGo/"; | ||
− | // SerCOM Vorbereitung | + | // MQTT Cleint Struktur anlegen |
+ | if ((mqttrc = MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS){ | ||
+ | printf("Failed to create mqttclient, return code %d\n", mqttrc); | ||
+ | exit(EXIT_FAILURE); | ||
+ | } | ||
+ | |||
+ | // SerCOM Vorbereitung | ||
struct termios oldtio,newtio; | struct termios oldtio,newtio; | ||
int fd; // FileDescriptor SerCOM | int fd; // FileDescriptor SerCOM | ||
int res; // SerCOM Einlesekontrolle | int res; // SerCOM Einlesekontrolle | ||
+ | |||
+ | // wenn in Kommandozeile die Schnittstelle mitgegeben wird, dann nimm diese sonst versuche default | ||
+ | if (argc > 1) | ||
+ | fd = open(argv[1], O_RDWR | O_NOCTTY ); | ||
+ | else | ||
+ | fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY ); | ||
+ | if (fd <0) { | ||
+ | perror(MODEMDEVICE); | ||
+ | exit(-1); | ||
+ | } | ||
+ | |||
+ | // sichere die aktuellen Einstellungen | ||
+ | tcgetattr(fd,&oldtio); | ||
+ | |||
+ | // baue die neuen Einstellungen zusammen | ||
+ | bzero(&newtio, sizeof(newtio)); | ||
+ | newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD; | ||
+ | newtio.c_iflag = IGNPAR | IXON | IXOFF; | ||
+ | newtio.c_oflag = 0; | ||
+ | newtio.c_lflag = 0; | ||
+ | newtio.c_cc[VTIME] = 0; /* inter-character timer unused */ | ||
+ | newtio.c_cc[VMIN] = 1; /* blocking read until 1 chars received */ | ||
+ | |||
+ | tcflush(fd, TCIFLUSH); | ||
+ | tcsetattr(fd,TCSANOW,&newtio); | ||
+ | |||
+ | setvbuf(stdout, (char *)NULL, _IONBF, 0); | ||
+ | |||
+ | // hier sind alle Vorbereitungen (SERCOM, MQTT) abgeschlossen jetzt koennen die Daten des Interfaces eingelesen, aufbereitet und per MQTT gesendet werden | ||
+ | // 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) | ||
+ | // wenn diese Folge erkannt wird bestimmen die beiden folgenden Bytes den Typ des Paketes | ||
+ | while (STOP==FALSE) { // Endlosschleife | ||
+ | |||
+ | res = read(fd,buf,1); | ||
+ | |||
+ | //sobald ein AA kommt beginne die Beobachtung | ||
+ | if ((buf[0]==170) && (syncstate==5)){ | ||
+ | syncstate=0; | ||
+ | } | ||
+ | if ((buf[0]==170) && (syncstate==0)){ // wenn der syncstate 0 (gleich Anfang) und ein AA erkannt wird dann setze sysncstate=1 | ||
+ | syncstate=1; | ||
+ | merker[0]=buf[0]; | ||
+ | } | ||
+ | if ((buf[0]==85) && (syncstate==1)){ // wenn der syncstate 1 (AA bereits erkannt) und ein 55 erkannt wird dann setze sysncstate=2 | ||
+ | syncstate=2; | ||
+ | merker[1]=buf[0]; | ||
+ | } | ||
+ | if ((buf[0]==85) && (syncstate==2)){ // wenn der syncstate 2 (AA 55 bereits erkannt) und ein 55 erkannt wird dann setze sysncstate=3 | ||
+ | syncstate=3; | ||
+ | merker[2]=buf[0]; | ||
+ | } | ||
+ | if ((buf[0]==170) && (syncstate==3)){ // wenn der syncstate 3 (AA 55 55 bereits erkannt) und ein AA erkannt wird dann setze sysncstate=4 | ||
+ | syncstate=4; | ||
+ | merker[3]=buf[0]; | ||
+ | state=0; | ||
+ | } | ||
+ | // wenn AA 55 55 AA erkannt wurde steht syncstate auf 4 , in merker[0-3] befindet sich die Syncfolge und state ist 0 | ||
+ | // wenn das nachfolgende Byte entweder 01 02 oder 03 ist ist alles wie erwartet und kann weitergehen syncstate = 5 | ||
+ | if (((buf[0]==1)||(buf[0]==2)||(buf[0]==3)) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==4)){ | ||
+ | merker[4]=buf[0]; | ||
+ | syncstate=5; | ||
+ | } | ||
+ | // 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) | ||
+ | |||
+ | if ((buf[0]==0) && (merker[4]==1) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){ | ||
+ | state=10; // state 10 bereit fuer 0100 Daten fuer das LC-Display | ||
+ | printflag=FALSE; | ||
+ | for(i=0;i<5;i++)merker[i]=0; | ||
+ | |||
+ | } | ||
+ | if ((buf[0]==0) && (merker[4]==2) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){ | ||
+ | state=20; // state 20 bereit fuer 0200 hat keinen (?) Inhalt -> keine Auswertung | ||
+ | printflag=FALSE; | ||
+ | for(i=0;i<5;i++)merker[i]=0; | ||
+ | |||
+ | } | ||
+ | if ((buf[0]==0) && (merker[4]==3) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){ | ||
+ | state=30; // state 30 bereit fuer 0300 Datensatze | ||
+ | printflag=FALSE; | ||
+ | for(i=0;i<5;i++)merker[i]=0; | ||
+ | dsIndex=0; | ||
+ | |||
+ | } | ||
+ | if ((buf[0]==1) && (merker[4]==3) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){ | ||
+ | state=31; // state 31 bereit fuer 0301 Datenfaelder | ||
+ | printflag=FALSE; | ||
+ | for(i=0;i<5;i++)merker[i]=0; | ||
+ | dfIndex=0; | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | // state 10 und 20 werden nicht ausgewertet | ||
+ | if ((state==10) && printflag) { | ||
+ | |||
+ | } | ||
+ | else if ((state==20) && printflag) { | ||
+ | |||
+ | } | ||
+ | else if ((state==30) && printflag){ | ||
+ | |||
+ | if(dsIndex<100)datensatz[dsIndex++]=buf[0]; | ||
+ | } | ||
+ | else if ((state==31) && printflag) { | ||
+ | |||
+ | if(dfIndex<100)datenfeld[dfIndex++]=buf[0]; | ||
+ | } | ||
+ | else{ | ||
+ | //printf("syncstate: %d, state: %d, %X\n\r",syncstate,state,buf[0]); | ||
+ | } | ||
+ | |||
+ | printflag=TRUE; | ||
+ | |||
+ | if (zeitzaehler==10000){ | ||
+ | // es wird etwa 3 mal pro Minute eine Auswahl der Datensaetze ausgegeben | ||
+ | // Datum: 18.09.2021 | ||
+ | // Message published, return code 0 | ||
+ | // Uhrzeit: 12:17 | ||
+ | // Message published, return code 0 | ||
+ | // Kollektor: 58.6 °C | ||
+ | // Message published, return code 0 | ||
+ | // Speicher unten: 49.2 °C | ||
+ | // Message published, return code 0 | ||
+ | // Speicher oben: 52.1 °C | ||
+ | // Message published, return code 0 | ||
+ | // Rücklaufanhebung T7: 52.0 °C | ||
+ | // Message published, return code 0 | ||
+ | // Rücklaufanhebung T8: 28.1 °C | ||
+ | // Message published, return code 0 | ||
+ | // Ausgang 1: 60% | ||
+ | // Message published, return code 0 | ||
+ | // Ausgang 6: 100% | ||
+ | // Message published, return code 0 | ||
+ | // Speicher 2: 15632h | ||
+ | // Message published, return code 0 | ||
+ | |||
+ | conn_opts.keepAliveInterval = 20; | ||
+ | conn_opts.cleansession = 1; | ||
+ | // Baue MQTT Verbindung auf | ||
+ | if ((mqttrc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS){ | ||
+ | printf("Failed to connect, return code %d\n", mqttrc); | ||
+ | exit(EXIT_FAILURE); | ||
+ | } | ||
+ | //Datum | ||
+ | formatieren(DATUM,datensatz[2],datensatz[3]); | ||
+ | printf("Datum: %s\n",datum); | ||
+ | strcpy(topic,basetopic); | ||
+ | strcat(topic,"Datum"); | ||
+ | pubmsg.payload = datum; | ||
+ | pubmsg.payloadlen = (int)strlen(datum); | ||
+ | pubmsg.qos = QOS; | ||
+ | pubmsg.retained = 0; | ||
+ | if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){ | ||
+ | printf("Failed to publish message, return code %d\n", mqttrc); | ||
+ | exit(EXIT_FAILURE); | ||
+ | }else{ | ||
+ | printf("Message published, return code %d\n", mqttrc); | ||
+ | } | ||
+ | //Uhrzeit | ||
+ | formatieren(UHRZEIT,datensatz[4],datensatz[5]); | ||
+ | printf("Uhrzeit: %s\n",uhrzeit); | ||
+ | strcpy(topic,basetopic); | ||
+ | strcat(topic,"Uhrzeit"); | ||
+ | pubmsg.payload = uhrzeit; | ||
+ | pubmsg.payloadlen = (int)strlen(uhrzeit); | ||
+ | pubmsg.qos = QOS; | ||
+ | pubmsg.retained = 0; | ||
+ | if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){ | ||
+ | printf("Failed to publish message, return code %d\n", mqttrc); | ||
+ | exit(EXIT_FAILURE); | ||
+ | }else{ | ||
+ | printf("Message published, return code %d\n", mqttrc); | ||
+ | } | ||
+ | //Kollektor | ||
+ | formatieren(TEMPERATUR,datensatz[6],datensatz[7]); | ||
+ | printf("Kollektor: %s\n",temperatur); | ||
+ | strcpy(topic,basetopic); | ||
+ | strcat(topic,"Kollektor/Temperatur"); | ||
+ | pubmsg.payload = temperatur; | ||
+ | pubmsg.payloadlen = (int)strlen(temperatur); | ||
+ | pubmsg.qos = QOS; | ||
+ | pubmsg.retained = 0; | ||
+ | if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){ | ||
+ | printf("Failed to publish message, return code %d\n", mqttrc); | ||
+ | exit(EXIT_FAILURE); | ||
+ | }else{ | ||
+ | printf("Message published, return code %d\n", mqttrc); | ||
+ | } | ||
+ | //Speicher unten | ||
+ | formatieren(TEMPERATUR,datensatz[8],datensatz[9]); | ||
+ | printf("Speicher unten: %s\n",temperatur); | ||
+ | strcpy(topic,basetopic); | ||
+ | strcat(topic,"Speicher/unten/Temperatur"); | ||
+ | pubmsg.payload = temperatur; | ||
+ | pubmsg.payloadlen = (int)strlen(temperatur); | ||
+ | pubmsg.qos = QOS; | ||
+ | pubmsg.retained = 0; | ||
+ | if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){ | ||
+ | printf("Failed to publish message, return code %d\n", mqttrc); | ||
+ | exit(EXIT_FAILURE); | ||
+ | }else{ | ||
+ | printf("Message published, return code %d\n", mqttrc); | ||
+ | } | ||
+ | //Speicher oben | ||
+ | formatieren(TEMPERATUR,datensatz[10],datensatz[11]); | ||
+ | printf("Speicher oben: %s\n",temperatur); | ||
+ | strcpy(topic,basetopic); | ||
+ | strcat(topic,"Speicher/oben/Temperatur"); | ||
+ | pubmsg.payload = temperatur; | ||
+ | pubmsg.payloadlen = (int)strlen(temperatur); | ||
+ | pubmsg.qos = QOS; | ||
+ | pubmsg.retained = 0; | ||
+ | if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){ | ||
+ | printf("Failed to publish message, return code %d\n", mqttrc); | ||
+ | exit(EXIT_FAILURE); | ||
+ | }else{ | ||
+ | printf("Message published, return code %d\n", mqttrc); | ||
+ | } | ||
+ | //Rücklaufanhebung T7 | ||
+ | formatieren(TEMPERATUR,datensatz[18],datensatz[19]); | ||
+ | printf("Rücklaufanhebung T7: %s\n",temperatur); | ||
+ | strcpy(topic,basetopic); | ||
+ | strcat(topic,"Rücklaufanhebung/T7/Temperatur"); | ||
+ | pubmsg.payload = temperatur; | ||
+ | pubmsg.payloadlen = (int)strlen(temperatur); | ||
+ | pubmsg.qos = QOS; | ||
+ | pubmsg.retained = 0; | ||
+ | if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){ | ||
+ | printf("Failed to publish message, return code %d\n", mqttrc); | ||
+ | exit(EXIT_FAILURE); | ||
+ | }else{ | ||
+ | printf("Message published, return code %d\n", mqttrc); | ||
+ | } | ||
+ | //Rücklaufanhebung T8 | ||
+ | formatieren(TEMPERATUR,datensatz[20],datensatz[21]); | ||
+ | printf("Rücklaufanhebung T8: %s\n",temperatur); | ||
+ | strcpy(topic,basetopic); | ||
+ | strcat(topic,"Rücklaufanhebung/T8/Temperatur"); | ||
+ | pubmsg.payload = temperatur; | ||
+ | pubmsg.payloadlen = (int)strlen(temperatur); | ||
+ | pubmsg.qos = QOS; | ||
+ | pubmsg.retained = 0; | ||
+ | if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){ | ||
+ | printf("Failed to publish message, return code %d\n", mqttrc); | ||
+ | exit(EXIT_FAILURE); | ||
+ | }else{ | ||
+ | printf("Message published, return code %d\n", mqttrc); | ||
+ | } | ||
+ | //Ausgang 1 | ||
+ | formatieren(PROZENT,datensatz[32],0); | ||
+ | printf("Ausgang 1: %s\n",prozent); | ||
+ | strcpy(topic,basetopic); | ||
+ | strcat(topic,"Ausgang/1/Prozent"); | ||
+ | pubmsg.payload = prozent; | ||
+ | pubmsg.payloadlen = (int)strlen(prozent); | ||
+ | pubmsg.qos = QOS; | ||
+ | pubmsg.retained = 0; | ||
+ | if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){ | ||
+ | printf("Failed to publish message, return code %d\n", mqttrc); | ||
+ | exit(EXIT_FAILURE); | ||
+ | }else{ | ||
+ | printf("Message published, return code %d\n", mqttrc); | ||
+ | } | ||
+ | //Ausgang 6 | ||
+ | formatieren(PROZENT,datensatz[37],0); | ||
+ | printf("Ausgang 6: %s\n",prozent); | ||
+ | strcpy(topic,basetopic); | ||
+ | strcat(topic,"Ausgang/6/Prozent"); | ||
+ | pubmsg.payload = prozent; | ||
+ | pubmsg.payloadlen = (int)strlen(prozent); | ||
+ | pubmsg.qos = QOS; | ||
+ | pubmsg.retained = 0; | ||
+ | if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){ | ||
+ | printf("Failed to publish message, return code %d\n", mqttrc); | ||
+ | exit(EXIT_FAILURE); | ||
+ | }else{ | ||
+ | printf("Message published, return code %d\n", mqttrc); | ||
+ | } | ||
+ | // Speicherstunden | ||
+ | formatieren(SPEICHER2,datensatz[50],datensatz[51]); | ||
+ | printf("Speicher 2: %s\n",stunden); | ||
+ | strcpy(topic,basetopic); | ||
+ | strcat(topic,"Speicher/Stunden"); | ||
+ | pubmsg.payload = stunden; | ||
+ | pubmsg.payloadlen = (int)strlen(stunden); | ||
+ | pubmsg.qos = QOS; | ||
+ | pubmsg.retained = 0; | ||
+ | if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){ | ||
+ | printf("Failed to publish message, return code %d\n", mqttrc); | ||
+ | exit(EXIT_FAILURE); | ||
+ | }else{ | ||
+ | printf("Message published, return code %d\n", mqttrc); | ||
+ | } | ||
+ | /* printf("Waiting for up to %d seconds for publication of %s\n" | ||
+ | "on topic %s for client with ClientID: %s\n", | ||
+ | (int)(TIMEOUT/1000), PAYLOAD, TOPIC, CLIENTID); | ||
+ | rc = MQTTClient_waitForCompletion(client, token, TIMEOUT); | ||
+ | printf("Message with delivery token %d delivered\n", token); | ||
+ | */ | ||
+ | if ((mqttrc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS){ | ||
+ | printf("Failed to disconnect, return code %d\n", mqttrc); | ||
+ | } | ||
+ | zeitzaehler=0; | ||
+ | } | ||
+ | zeitzaehler++; | ||
+ | if (zeitzaehler%100000==0)printf("%d\n",zeitzaehler); // Lebenszeichen | ||
+ | |||
+ | } | ||
+ | |||
+ | close(fd); // schliesze serielle Schnittstelle | ||
+ | |||
+ | tcsetattr(fd,TCSANOW,&oldtio); // stelle die alte ComConfig wieder her | ||
+ | |||
+ | MQTTClient_destroy(&client); // beende die MQTT Kommunikation | ||
+ | |||
+ | return EXIT_SUCCESS; | ||
+ | } | ||
+ | #include <string.h> | ||
+ | #include <stdlib.h> | ||
+ | #include <stdio.h> | ||
+ | #include <unistd.h> | ||
+ | #include <stdbool.h> | ||
+ | #include <time.h> | ||
+ | #include <sys/types.h> | ||
+ | #include <sys/stat.h> | ||
+ | #include <fcntl.h> | ||
+ | #include <termios.h> // termios is the API that is in general recommended for serial I/O in Unix. | ||
+ | #include "MQTTClient.h" | ||
+ | |||
+ | // MQTT defines | ||
+ | #define ADDRESS "tcp://192.168.178.12:1883" | ||
+ | //#define ADDRESS "tcp://localhost:1883" | ||
+ | #define CLIENTID "SunGo" | ||
+ | //#define TOPIC "MQTTExamples" | ||
+ | //#define PAYLOAD "Hello World!" | ||
+ | #define QOS 0 | ||
+ | #define TIMEOUT 10000L | ||
+ | |||
+ | // SERCOM defines | ||
+ | #define BAUDRATE B115200 | ||
+ | #define MODEMDEVICE "/dev/ttyS1" | ||
+ | #define _POSIX_SOURCE 1 /* POSIX compliant source */ | ||
+ | #define FALSE 0 | ||
+ | #define TRUE 1 | ||
+ | |||
+ | |||
+ | // SunGo defines | ||
+ | #define DUMMY 0 | ||
+ | #define TEMPERATUR 1 // °C | ||
+ | #define STRAHLUNG 2 // W/m² | ||
+ | #define SPEICHER1 7 // kwh | ||
+ | #define DATUM 8 | ||
+ | #define UHRZEIT 9 | ||
+ | #define PROZENT 10 // % | ||
+ | #define FUNKTION1 11 | ||
+ | #define FUNKTION2 12 | ||
+ | #define SPEICHER2 15 // h | ||
+ | #define VOLUMENSTROM 19 // l/min | ||
+ | |||
+ | |||
+ | 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 | ||
+ | // solange das nicht realisiert ist laeuft die "main-Schleife" endlos. | ||
+ | |||
+ | |||
+ | // globale Variablen | ||
+ | char datum[11]; | ||
+ | char uhrzeit[7]; | ||
+ | char temperatur[25]; | ||
+ | char prozent[7]; | ||
+ | char strahlung[8]; | ||
+ | char fehler[17]; | ||
+ | char stunden[8]; | ||
+ | char dummy[7]; | ||
+ | |||
+ | // hexadezimale Darstellung in dezimale umstellen | ||
+ | unsigned int hextodec(char hex[10]){ | ||
+ | unsigned int decimal=0; | ||
+ | unsigned int length=0; | ||
+ | unsigned int base = 1; | ||
+ | int i=0; | ||
+ | |||
+ | while(hex[i]!='\0'){ | ||
+ | i++; | ||
+ | } | ||
+ | length=i; | ||
+ | |||
+ | //printf("hextodec %s\n\r",hex); | ||
+ | //printf("length %d\n\r",length); | ||
+ | |||
+ | for(i = length-1; i >= 0; i--){ | ||
+ | //printf("i: %d\n\r",i); | ||
+ | if (i<0)i=0; | ||
+ | if(hex[i] >= '0' && hex[i] <= '9'){ | ||
+ | decimal += ((unsigned char)hex[i] - 48) * base; | ||
+ | base *= 16; | ||
+ | } | ||
+ | else if(hex[i] >= 'A' && hex[i] <= 'F'){ | ||
+ | decimal += ((unsigned char)hex[i] - 55) * base; | ||
+ | base *= 16; | ||
+ | } | ||
+ | else if(hex[i] >= 'a' && hex[i] <= 'f'){ | ||
+ | decimal += ((unsigned char)hex[i] - 87) * base; | ||
+ | base *= 16; | ||
+ | } | ||
+ | } | ||
+ | //printf("decimal %d\n\r",decimal); | ||
+ | return decimal; | ||
+ | } | ||
+ | |||
+ | void delay(int number_of_seconds) // wird doch nicht gebraucht | ||
+ | { | ||
+ | // Converting time into milli_seconds | ||
+ | int milli_seconds = 1000 * number_of_seconds; | ||
+ | |||
+ | // Storing start time | ||
+ | clock_t start_time = clock(); | ||
+ | |||
+ | // looping till required time is not achieved | ||
+ | while (clock() < start_time + milli_seconds) | ||
+ | ; | ||
+ | } | ||
+ | |||
+ | // allgemeine Funktion; die verschiedenen Typen werden ueber switch case angesprochen | ||
+ | void formatieren(unsigned char typ,unsigned char lowbyte,unsigned char highbyte){ | ||
+ | char data[10]=""; // dient der Aufnahme des zu wandelnden Wertes gebildet aus highbyte und lowbyte | ||
+ | char tmp[3]=""; // hilfvariable | ||
+ | char formatted[25]=""; | ||
+ | char dataStr[5]=""; | ||
+ | unsigned int dataInteger; | ||
+ | float dataFloat; | ||
+ | unsigned int dataStunden, dataMinuten; | ||
+ | |||
+ | //memset(formatted,'\0',sizeof(formatted)); | ||
+ | //memset(data,'\0',sizeof(data)); | ||
+ | //memset(tmp,'\0',sizeof(tmp)); | ||
+ | |||
+ | // aus den beiden Einzelwerten wird der "Gesamtwert in der "richtigen" Reihenfolge gebildet | ||
+ | sprintf(tmp,"%02X",highbyte); | ||
+ | strcpy(data,tmp); | ||
+ | sprintf(tmp,"%02X",lowbyte); | ||
+ | strcat(data,tmp); | ||
+ | |||
+ | //printf("Data: %s\n",data); | ||
+ | |||
+ | dataInteger=hextodec(data); | ||
+ | |||
+ | switch(typ) { | ||
+ | case DUMMY: if(TRUE){ | ||
+ | strcpy(dummy,data); | ||
+ | } | ||
+ | else{ | ||
+ | strcpy(dummy,"Error!"); | ||
+ | } | ||
+ | break; | ||
+ | case DATUM: sprintf(dataStr,"%d",dataInteger); | ||
+ | strcpy(formatted,"00.00.2021"); | ||
+ | if(strlen(dataStr)==3){ | ||
+ | formatted[0]=dataStr[1]; | ||
+ | formatted[1]=dataStr[2]; | ||
+ | formatted[4]=dataStr[0]; | ||
+ | strcpy(datum,formatted); | ||
+ | } | ||
+ | else if(strlen(dataStr)==4){ | ||
+ | formatted[0]=dataStr[2]; | ||
+ | formatted[1]=dataStr[3]; | ||
+ | formatted[3]=dataStr[0]; | ||
+ | formatted[4]=dataStr[1]; | ||
+ | strcpy(datum,formatted); | ||
+ | } | ||
+ | else{ | ||
+ | strcpy(datum,"Error!"); | ||
+ | } | ||
+ | break; | ||
+ | case UHRZEIT: dataStunden=(unsigned int)dataInteger/60; | ||
+ | dataMinuten=dataInteger-(dataStunden*60); | ||
+ | if(TRUE){ // hier koennte man die gueltig der stunden und minuten noch testen | ||
+ | sprintf(formatted,"%02d:%02d",dataStunden,dataMinuten); | ||
+ | strcpy(uhrzeit,formatted); | ||
+ | } | ||
+ | else{ | ||
+ | strcpy(uhrzeit,"Error!"); | ||
+ | } | ||
+ | break; | ||
+ | case TEMPERATUR: dataFloat=(float)dataInteger/10.0; | ||
+ | if(TRUE){ | ||
+ | //sprintf(formatted,"%5.1f °C (%d) ",dataFloat,dataInteger); | ||
+ | sprintf(formatted,"%5.1f °C",dataFloat); | ||
+ | strcpy(temperatur,formatted); | ||
+ | } | ||
+ | else{ | ||
+ | strcpy(temperatur,"Error!\0"); | ||
+ | } | ||
+ | break; | ||
+ | case SPEICHER2: if(TRUE){ | ||
+ | sprintf(formatted,"%dh",dataInteger); | ||
+ | strcpy(stunden,formatted); | ||
+ | } | ||
+ | else{ | ||
+ | strcpy(stunden,"Error!"); | ||
+ | } | ||
+ | break; | ||
+ | case PROZENT: if(TRUE){ | ||
+ | sprintf(formatted,"%3d%%",dataInteger); | ||
+ | strcpy(prozent,formatted); | ||
+ | } | ||
+ | else{ | ||
+ | strcpy(prozent,"Error!"); | ||
+ | } | ||
+ | break; | ||
+ | case STRAHLUNG: if(TRUE){ | ||
+ | sprintf(formatted,"%d W/m² ",dataInteger); | ||
+ | strcpy(strahlung,formatted); | ||
+ | } | ||
+ | else{ | ||
+ | strcpy(strahlung,"Error!\0"); | ||
+ | } | ||
+ | break; | ||
+ | default: printf("Type Error (unknown)\n"); break; | ||
+ | } | ||
+ | |||
+ | return; | ||
+ | } | ||
+ | |||
+ | int main(int argc, char **argv) | ||
+ | { int i; // Schleifenzaehler allgemein | ||
+ | unsigned int state=0, syncstate=0; // state 10,20,30 oder 31 entsprechend 0100, 0200, 0300, 0301 | ||
+ | unsigned int dsIndex, dfIndex; // Zeiger auf Datensatz und Datenfeld | ||
+ | unsigned long zeitzaehler=0; // Ausgabe verlangsamen 500000 etwa 1 Minute | ||
+ | |||
+ | unsigned char buf[1]; | ||
+ | unsigned char merker[6]; | ||
+ | unsigned char datensatz[100]; | ||
+ | unsigned char datenfeld[100]; | ||
+ | unsigned char datenfelder[50][16]; | ||
+ | bool printflag; | ||
+ | |||
+ | // MQTT Vorbereitung | ||
+ | MQTTClient client; | ||
+ | MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; | ||
+ | MQTTClient_message pubmsg = MQTTClient_message_initializer; | ||
+ | MQTTClient_deliveryToken token; | ||
+ | int mqttrc; // | ||
+ | char topic[255]; // zur Aufnahme Werte unterhalb des basetopic | ||
+ | char *basetopic = "Haus/Heizung/Solaranlage/SunGo/"; | ||
// MQTT Cleint Struktur anlegen | // MQTT Cleint Struktur anlegen | ||
Zeile 256: | Zeile 807: | ||
} | } | ||
+ | // SerCOM Vorbereitung | ||
+ | struct termios oldtio,newtio; | ||
+ | int fd; // FileDescriptor SerCOM | ||
+ | int res; // SerCOM Einlesekontrolle | ||
+ | |||
// wenn in Kommandozeile die Schnittstelle mitgegeben wird, dann nimm diese sonst versuche default | // wenn in Kommandozeile die Schnittstelle mitgegeben wird, dann nimm diese sonst versuche default | ||
if (argc > 1) | if (argc > 1) | ||
Zeile 283: | Zeile 839: | ||
setvbuf(stdout, (char *)NULL, _IONBF, 0); | setvbuf(stdout, (char *)NULL, _IONBF, 0); | ||
− | + | // hier sind alle Vorbereitungen (SERCOM, MQTT) abgeschlossen jetzt koennen die Daten des Interfaces eingelesen, aufbereitet und per MQTT gesendet werden | |
+ | // 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) | ||
+ | // wenn diese Folge erkannt wird bestimmen die beiden folgenden Bytes den Typ des Paketes | ||
+ | while (STOP==FALSE) { // Endlosschleife | ||
res = read(fd,buf,1); | res = read(fd,buf,1); | ||
Zeile 291: | Zeile 850: | ||
syncstate=0; | syncstate=0; | ||
} | } | ||
− | if ((buf[0]==170) && (syncstate==0)){ | + | if ((buf[0]==170) && (syncstate==0)){ // wenn der syncstate 0 (gleich Anfang) und ein AA erkannt wird dann setze sysncstate=1 |
syncstate=1; | syncstate=1; | ||
merker[0]=buf[0]; | merker[0]=buf[0]; | ||
} | } | ||
− | if ((buf[0]==85) && (syncstate==1)){ | + | if ((buf[0]==85) && (syncstate==1)){ // wenn der syncstate 1 (AA bereits erkannt) und ein 55 erkannt wird dann setze sysncstate=2 |
syncstate=2; | syncstate=2; | ||
merker[1]=buf[0]; | merker[1]=buf[0]; | ||
} | } | ||
− | if ((buf[0]==85) && (syncstate==2)){ | + | if ((buf[0]==85) && (syncstate==2)){ // wenn der syncstate 2 (AA 55 bereits erkannt) und ein 55 erkannt wird dann setze sysncstate=3 |
syncstate=3; | syncstate=3; | ||
merker[2]=buf[0]; | merker[2]=buf[0]; | ||
} | } | ||
− | if ((buf[0]==170) && (syncstate==3)){ | + | if ((buf[0]==170) && (syncstate==3)){ // wenn der syncstate 3 (AA 55 55 bereits erkannt) und ein AA erkannt wird dann setze sysncstate=4 |
syncstate=4; | syncstate=4; | ||
merker[3]=buf[0]; | merker[3]=buf[0]; | ||
state=0; | state=0; | ||
} | } | ||
+ | // wenn AA 55 55 AA erkannt wurde steht syncstate auf 4 , in merker[0-3] befindet sich die Syncfolge und state ist 0 | ||
+ | // wenn das nachfolgende Byte entweder 01 02 oder 03 ist ist alles wie erwartet und kann weitergehen syncstate = 5 | ||
if (((buf[0]==1)||(buf[0]==2)||(buf[0]==3)) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==4)){ | if (((buf[0]==1)||(buf[0]==2)||(buf[0]==3)) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==4)){ | ||
merker[4]=buf[0]; | merker[4]=buf[0]; | ||
syncstate=5; | syncstate=5; | ||
} | } | ||
− | + | // 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) | |
if ((buf[0]==0) && (merker[4]==1) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){ | if ((buf[0]==0) && (merker[4]==1) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){ | ||
− | state=10; // state 10 bereit fuer 0100 | + | state=10; // state 10 bereit fuer 0100 Daten fuer das LC-Display |
printflag=FALSE; | printflag=FALSE; | ||
for(i=0;i<5;i++)merker[i]=0; | for(i=0;i<5;i++)merker[i]=0; | ||
Zeile 321: | Zeile 882: | ||
} | } | ||
if ((buf[0]==0) && (merker[4]==2) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){ | if ((buf[0]==0) && (merker[4]==2) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){ | ||
− | state=20; // state | + | state=20; // state 20 bereit fuer 0200 hat keinen (?) Inhalt -> keine Auswertung |
printflag=FALSE; | printflag=FALSE; | ||
for(i=0;i<5;i++)merker[i]=0; | for(i=0;i<5;i++)merker[i]=0; | ||
Zeile 327: | Zeile 888: | ||
} | } | ||
if ((buf[0]==0) && (merker[4]==3) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){ | if ((buf[0]==0) && (merker[4]==3) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){ | ||
− | state=30; // state | + | state=30; // state 30 bereit fuer 0300 Datensatze |
printflag=FALSE; | printflag=FALSE; | ||
for(i=0;i<5;i++)merker[i]=0; | for(i=0;i<5;i++)merker[i]=0; | ||
Zeile 334: | Zeile 895: | ||
} | } | ||
if ((buf[0]==1) && (merker[4]==3) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){ | if ((buf[0]==1) && (merker[4]==3) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){ | ||
− | state=31; // state | + | state=31; // state 31 bereit fuer 0301 Datenfaelder |
printflag=FALSE; | printflag=FALSE; | ||
for(i=0;i<5;i++)merker[i]=0; | for(i=0;i<5;i++)merker[i]=0; | ||
Zeile 342: | Zeile 903: | ||
− | + | // state 10 und 20 werden nicht ausgewertet | |
if ((state==10) && printflag) { | if ((state==10) && printflag) { | ||
Zeile 364: | Zeile 925: | ||
if (zeitzaehler==10000){ | if (zeitzaehler==10000){ | ||
+ | // es wird etwa 3 mal pro Minute eine Auswahl der Datensaetze ausgegeben | ||
+ | // Datum: 18.09.2021 | ||
+ | // Message published, return code 0 | ||
+ | // Uhrzeit: 12:17 | ||
+ | // Message published, return code 0 | ||
+ | // Kollektor: 58.6 °C | ||
+ | // Message published, return code 0 | ||
+ | // Speicher unten: 49.2 °C | ||
+ | // Message published, return code 0 | ||
+ | // Speicher oben: 52.1 °C | ||
+ | // Message published, return code 0 | ||
+ | // Rücklaufanhebung T7: 52.0 °C | ||
+ | // Message published, return code 0 | ||
+ | // Rücklaufanhebung T8: 28.1 °C | ||
+ | // Message published, return code 0 | ||
+ | // Ausgang 1: 60% | ||
+ | // Message published, return code 0 | ||
+ | // Ausgang 6: 100% | ||
+ | // Message published, return code 0 | ||
+ | // Speicher 2: 15632h | ||
+ | // Message published, return code 0 | ||
+ | |||
conn_opts.keepAliveInterval = 20; | conn_opts.keepAliveInterval = 20; | ||
conn_opts.cleansession = 1; | conn_opts.cleansession = 1; | ||
Zeile 537: | Zeile 1.120: | ||
} | } | ||
− | close(fd); | + | close(fd); // schliesze serielle Schnittstelle |
− | tcsetattr(fd,TCSANOW,&oldtio); | + | tcsetattr(fd,TCSANOW,&oldtio); // stelle die alte ComConfig wieder her |
− | MQTTClient_destroy(&client); | + | MQTTClient_destroy(&client); // beende die MQTT Kommunikation |
return EXIT_SUCCESS; | return EXIT_SUCCESS; | ||
} | } | ||
+ | |||
</syntaxhighlight> | </syntaxhighlight> | ||
</div></div> | </div></div> |
Version vom 18. September 2021, 13:29 Uhr
Inhaltsverzeichnis
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
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
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
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
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 }