Jump to content

Motion Detector mit Mail versand


Gast LinTec

Recommended Posts

Moin zusammen,

ich habe folgendes Problem. Mein Motion Detektor soll bei einer Bewegung eine E-Mail versenden. Das Programm soll so lange laufen, bis getchar() einen Wert erhält. Das Problem aber ist, dass das Programm automatisch endet. Ich habe es schon mit fflush(stdin) versucht, aber es scheint nichts zu bringen. Vielleicht fällt einem von euch was auf, oder kann mir helfen. Hier der Code:

 

//

//  main.c

//  Motion_Detector_V01

 

 

#include <stdio.h>

#include <unistd.h>

#include "brick_master.h"

#include "bricklet_industrial_quad_relay.h"

#include "ip_connection.h"

#include "bricklet_motion_detector.h"

#include "bricklet_piezo_speaker.h"

#include <string.h>

#include <errno.h>

 

//Globale Var

IPConnection ipcon;

 

//Sendmail functionality for detected motion

void sendmail(const char *to, const char *from, const char *subject, const char *message)

{

    FILE *mailpipe = popen("/usr/sbin/sendmail -t", "w");

    if (mailpipe != NULL) {

        fprintf(mailpipe, "%s", to);

        fprintf(mailpipe, "%s", from);

        fprintf(mailpipe, "%s", subject);

        fwrite(message, 1, strlen(message), mailpipe);

        pclose(mailpipe);

    }

    else {

        perror("Failed to invoke sendmail");

    }

    fflush(stdin);

}

 

// Callback function for detected motion

void cb_motion_detected(int argc, char** argv)

{

    PiezoSpeaker ps;

    IndustrialQuadRelay iqr;

   

    industrial_quad_relay_create(&iqr, "g3n", &ipcon);

    piezo_speaker_create(&ps, "iLP", &ipcon);

    piezo_speaker_morse_code(&ps, "----", 1500);

    printf("Motion Detected\n");

   

    sendmail("To: xxxxx@xx.de\n", "From: xxxxx@xx.com\n", "Subject: Test Mail\n\n","Test Nachricht");

   

    for(int i = 4; i >= 0; i--)

    {

        industrial_quad_relay_set_monoflop(&iqr, 1, 1, 1500);

        sleep(2);

    }

    fflush(stdin);

}

 

 

int main(int argc, const char * argv[])

{

    MotionDetector md;

   

    ipcon_create(&ipcon);

    motion_detector_create(&md, "kg6", &ipcon);

   

    //Check connection

    if(ipcon_connect(&ipcon, "localhost", 4223) < 0) {

        fprintf(stderr, "Could not connect to brickd\n");

        exit(1);

    }

   

    // Callback function MD

    motion_detector_register_callback(&md,

                                      MOTION_DETECTOR_CALLBACK_MOTION_DETECTED,

                                      (void *)cb_motion_detected,

                                      NULL);

 

    printf("Press any key to exit\n");

    getchar();

   

    //ipcon disconnect

    ipcon_destroy(&ipcon);

}

Link zu diesem Kommentar
Share on other sites

Ich kann da auf die Schnelle nichts finden was böse aussieht. Was genau passiert denn wenn sich das Programm beendet? Kannst du vor dem ipcon_destroy mal ein printf machen um zu sehen ob das getchar aus irgendwelchen Gründen ausgelöst wird?

 

Wenn sich das Programm nicht normal beendet, gibt es einen Segfault oder irgendeine andere Fehlermeldung?

Link zu diesem Kommentar
Share on other sites

Der "cb_motion_detected" hat auf jeden Fall die falsche Signatur (sollte nur einen user_data-Parameter haben).

 

Außerdem registriert der Callback (falls er gerufen wird) Objekte, die nicht wieder de-registriert werden (relay + piezo-Speaker).

 

Wie weit kommt das Programm denn?

Kommt es bis zum

printf("Motion Detected\n");

?

 

Link zu diesem Kommentar
Share on other sites

@borg:

Folgendes wird mir zurückgeliefert:

Code:

    printf("Press any key to exit\n");

    int c;

    c = getchar();

    putchar©;

 

Ergebnis = \377 ==> Das ist im Stream

 

@remotecontrol

Das Programm läuft 1 mal sauber durch. Nur wartet er nicht auf das getchar();

 

 

Was ich bis jetzt rausgefunden habe ist, dass es in der sendmail Funktion liegen muss. Wenn ich den sendmail Aufruf im Callback auskommentiere, dann funktioniert es.

 

Ich war jetzt am überlegen, ob ich folgendes machen soll:

while((c = getchar()) != EOF);

 

Dann sollte er eigentlich auch die Tastenkombination warten, um das Programm zu beenden.

 

NACHTRAG:

Ich habe es jetzt mal mit "while((c = getchar()) != EOF);" probiert und das selbe Problem :-( Das Programm endet nach dem ersten Durchlauf.

Link zu diesem Kommentar
Share on other sites

Wie ist der Wert \377 gemeint: ist das der Output des putchar? Das wäre nämlich eine -1 oder EOF (d.h. c==EOF).

 

Sieht so aus, als würde der popen / close auch stdin schließen.

 

Evtl. ist es hier besser, die Anwendung über einen signal handler zu beenden, der auf ctrl-c oder sigterm reagiert.

 

Nachtrag:

fflush auf stdin ist keine gute Idee: das ist eigentlich nur für zum Schreiben geöffnete Steams zulässig.

Link zu diesem Kommentar
Share on other sites

@remotecontrol

Ich schau mir das mal an. Vielleicht gibt es da eine Möglichkeit.

 

Ich habe das Problem jetzt etwas kompliziert gelöst. Ich habe eine do while Schleife in der main Funktion eingebaut, die eine Globale Variable (ex) prüft. Diese Variable wird am Ende von sendmail auf 1 gesetzt. In der while Bedingung wird geprüft, ob ex == 1 ist. Das ist immer der Fall und somit habe ich eine Endlosschleife. Um diese zu beenden, habe ich eine IF Schleife benutzt, die die Variable code abfragt. Wenn code == 1, dann nutze GOTO und spring aus der WHILE Schleife und beende das Programm.

 

Hier der Source Code:

 

#include <stdio.h>

#include <unistd.h>

#include "brick_master.h"

#include "bricklet_industrial_quad_relay.h"

#include "ip_connection.h"

#include "bricklet_motion_detector.h"

#include "bricklet_piezo_speaker.h"

#include <string.h>

#include <errno.h>

 

//Globale Variablen

IPConnection ipcon;

int ex = 0;

 

//Sendmail functionality for detected motion

int sendmail(const char *to, const char *from, const char *subject, const char *message)

{

    FILE *mailpipe = popen("/usr/sbin/sendmail -t", "w");

    if (mailpipe != NULL) {

        fprintf(mailpipe, "%s", to);

        fprintf(mailpipe, "%s", from);

        fprintf(mailpipe, "%s", subject);

        fwrite(message, 1, strlen(message), mailpipe);

        pclose(mailpipe);

    }

    else {

        perror("Failed to invoke sendmail");

    }

    printf("E-Mail wurde versendet!\n");

    ex = 1;

    return ex;

}

 

// Callback function for detected motion

void cb_motion_detected(void *user_data)

{

    (void)user_data;

    PiezoSpeaker ps;

    IndustrialQuadRelay iqr;

   

    industrial_quad_relay_create(&iqr, "g3n", &ipcon);

    piezo_speaker_create(&ps, "iLP", &ipcon);

    piezo_speaker_morse_code(&ps, "----", 1500);

    printf("\nMotion Detected\n");

   

    for(int i = 2; i >= 0; i--)

    {

        industrial_quad_relay_set_monoflop(&iqr, 1, 1, 1500);

        sleep(2);

    }

    sendmail("To: xxxx@xx.de\n", "From: xxxx@xx.com\n", "Subject: Test Mail\n\n","Test Nachricht");

}

 

 

int main(int argc, const char * argv[])

{

    printf("Motion Detector is now running and active!\n");

    do {

        int code = 0;

    MotionDetector md;

   

    ipcon_create(&ipcon);

    motion_detector_create(&md, "kg6", &ipcon);

   

    //Check connection

    if(ipcon_connect(&ipcon, "localhost", 4223) < 0) {

        fprintf(stderr, "Could not connect to brickd\n");

        exit(1);

    }

   

    // Register detected callback to function cb_motion_detected

    motion_detector_register_callback(&md,

                                      MOTION_DETECTOR_CALLBACK_MOTION_DETECTED,

                                      (void *)cb_motion_detected, NULL);

   

        printf("Bitte Code eingeben: ");

        scanf("%i", &code);

       

        if(code == 1)

        {

            goto ende;

        }

       

    //ipcon disconnect

    ipcon_destroy(&ipcon);

    }

    while (ex == 1);

   

    ende:

    fclose(stdin);

}

Link zu diesem Kommentar
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Gast
Reply to this topic...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoji are allowed.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Clear editor

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

×
×
  • Neu erstellen...