Subversion Repositories heizung

Rev

Rev 8 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * (C) Copyright 2011 to 2015, 2024 by Andreas Theofilu <andreas@theosys.at>
 * All rights reserved!
 */
//#define SENSOR_ELV
#define SENSOR_ETHERNET

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <syslog.h>
#include <errno.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include "sensor.h"
#include "usb_comm.h"
#include "heizung.h"

#define CommandOn       0x0003
#define CommandOff      0x0000

typedef struct
{
    int pressure;
    int temperature;
    time_t tstamp;
} mpoint;

int HeatStatus;

static pthread_mutex_t fastmutex_ser = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t fastmutex_temp = PTHREAD_MUTEX_INITIALIZER;

#ifdef SENSOR_ELV
float GetTemp()
{
    int fd;
    long anz, offset;
    double delta_p;
    struct stat st;
    mpoint mp;
    time_t t;

    if ((fd = open(configs.Werte, O_RDONLY)) == -1)
    {
        syslog(LOG_DAEMON, "Error opening file %s: %s", configs.Werte, strerror(errno));
        return 9999.0;
    }

    if (fstat(fd, &st) == -1)
    {
        syslog(LOG_DAEMON, "Error stating file %s: %s", configs.Werte, strerror(errno));
        close(fd);
        return 9999.0;
    }

    if (st.st_size < sizeof(mpoint))
    {
        syslog(LOG_DAEMON, "No entries in file %s", configs.Werte);
        close(fd);
        return 9999.0;
    }

    anz = st.st_size / sizeof(mpoint);
    offset = (anz - 1) * sizeof(mpoint);

    lseek(fd, offset, 0);
    read(fd, &mp, sizeof(mpoint));
    close(fd);
    t = time(NULL);

    /*
     * Da unsere Temperaturmessung Teil des Drucksensors ist und der
     * Daemon durchaus einmal abstürzen kann, wodurch dann keine
     * brauchbare Temperatur mehr existiert, müssen wir hier sicher
     * stellen, das sich die Heizung abschaltet und das Programm
     * beendet. Das ist der Fall, wenn die letzte Messung mehr als
     * 10 Minuten zurück liegt.
     */
    if (t > (mp.tstamp + 600L))
    {
        SwitchOff();
        syslog(LOG_DAEMON, "Warning: No temperature was meassured in the last 10 minutes!");
        return 9999.0;
    }

    // Luftdruck
    delta_p = pow((1.0 - (6.5 * 256.0) / 288000.0), 5.255);
    ActPressure = (float)(mp.pressure / 10.0) / delta_p;
    // Temperatur
    ActTemperature = ((float)mp.temperature - 10.0) / 10.0;
    return ActTemperature;
}
#elif defined SENSOR_ETHERNET
float GetTemp(void)
{
    struct sockaddr_in sa;
    int socket_fd;

    sa.sin_family = AF_INET;
    sa.sin_port = htons(configs.TempPort);
    sa.sin_addr.s_addr = inet_addr(configs.IP);
    memset(sa.sin_zero, '\0', sizeof(sa.sin_zero));
    pthread_mutex_lock(&fastmutex_temp);

    socket_fd = socket(PF_INET, SOCK_STREAM, 0);

    if (socket_fd == -1)
    {
        pthread_mutex_unlock(&fastmutex_temp);
        syslog(LOG_DAEMON | LOG_ERR, "Could not create socket: %s", strerror(errno));
        return 0.0;
    }

    if (connect(socket_fd, (struct sockaddr*)&sa, sizeof(sa)) == -1)
    {
        pthread_mutex_unlock(&fastmutex_temp);
        syslog(LOG_DAEMON | LOG_ERR, "Error connecting!: %s", strerror(errno));
        return 0.0;
    }

    char message[512];
    memset(message, '\0', sizeof(message));
    int ret = recv(socket_fd, message, sizeof(message), 0);
    close(socket_fd);
    pthread_mutex_unlock(&fastmutex_temp);

    if (ret > 0)
    {
        ActTemperature = atof(message);
        ActPressure = 0.0;
        syslog(LOG_DAEMON | LOG_DEBUG, "Temperature: %0.1f", ActTemperature);
        return ActTemperature;
    }
    else
        return 0.0;
}
#else
#WARNING "sensor.c: No valid sensor defined!"
#endif

void SwitchOn()
{
    int set_bits;

    if (serialDev.switch_fd < 0)
    {
        syslog(LOG_DAEMON | LOG_ERR, "Es war kein File handle geöffnet! (EIN)");
        HeatStatus = 2;
        return;
    }

    set_bits = CommandOn;
    pthread_mutex_lock(&fastmutex_ser);

    if (ioctl(serialDev.switch_fd, TIOCMSET, &set_bits) == -1)
    {
        pthread_mutex_unlock(&fastmutex_ser);
        syslog(LOG_DAEMON | LOG_ERR, "Fehler beim Einschalten!");
        HeatStatus = 2;
        return;
    }

    pthread_mutex_unlock(&fastmutex_ser);
    syslog(LOG_DAEMON | LOG_INFO, "Heizung EIN (%.1f)", ActTemperature);
    HeatStatus = 1;
}

void SwitchOff()
{
    int set_bits;

    if (serialDev.switch_fd < 0)
    {
        syslog(LOG_DAEMON | LOG_ERR, "Es war kein File handle geöffnet! (AUS)");
        HeatStatus = 2;
        return;
    }

    set_bits = CommandOff;
    pthread_mutex_lock(&fastmutex_ser);

    if (ioctl(serialDev.switch_fd, TIOCMSET, &set_bits) == -1)
    {
        pthread_mutex_unlock(&fastmutex_ser);
        syslog(LOG_DAEMON | LOG_ERR, "Fehler beim Ausschalten!");
        HeatStatus = 2;
        return;
    }

    pthread_mutex_unlock(&fastmutex_ser);
    syslog(LOG_DAEMON | LOG_INFO, "Heizung AUS (%.1f)", ActTemperature);
    HeatStatus = 0;
}