Fri, 05 Apr 2024 16:19:39 +0200
Version 0.9.17a1. Revised starting and stopping the threads. Fixed stopping the command server thread. Moved one-wire tempeature sensors resolution correction to the one-wire thread. The devices thread fetches temperatures from the one-wire thread. The one-wire thread does everything for the temperature sensors. The command server uses private sockets. Still, only one session at the same time is handled.
configure | file | annotate | diff | comparison | revisions | |
configure.ac | file | annotate | diff | comparison | revisions | |
thermferm/Makefile | file | annotate | diff | comparison | revisions | |
thermferm/devices.c | file | annotate | diff | comparison | revisions | |
thermferm/one-wire.c | file | annotate | diff | comparison | revisions | |
thermferm/panel.c | file | annotate | diff | comparison | revisions | |
thermferm/server.c | file | annotate | diff | comparison | revisions | |
thermferm/simulator.c | file | annotate | diff | comparison | revisions | |
thermferm/thermferm.c | file | annotate | diff | comparison | revisions | |
thermferm/thermferm.h | file | annotate | diff | comparison | revisions |
--- a/configure Wed Apr 03 19:33:38 2024 +0200 +++ b/configure Fri Apr 05 16:19:39 2024 +0200 @@ -2037,7 +2037,7 @@ PACKAGE="mbsePi-apps" -VERSION="0.9.17" +VERSION="0.9.17a1" COPYRIGHT="Copyright (C) 2014-2024 Michiel Broek, All Rights Reserved" CYEARS="2014-2024"
--- a/configure.ac Wed Apr 03 19:33:38 2024 +0200 +++ b/configure.ac Fri Apr 05 16:19:39 2024 +0200 @@ -8,7 +8,7 @@ dnl General settings dnl After changeing the version number, run autoconf! PACKAGE="mbsePi-apps" -VERSION="0.9.17" +VERSION="0.9.17a1" COPYRIGHT="Copyright (C) 2014-2024 Michiel Broek, All Rights Reserved" CYEARS="2014-2024" AC_SUBST(PACKAGE)
--- a/thermferm/Makefile Wed Apr 03 19:33:38 2024 +0200 +++ b/thermferm/Makefile Fri Apr 05 16:19:39 2024 +0200 @@ -57,7 +57,7 @@ # Dependencies generated by make depend mqtt.o: thermferm.h rdconfig.h devices.h xutil.h delay.h mqtt.h thermferm.o: lock.h rdconfig.h server.h thermferm.h devices.h delay.h simulator.h lcd-pcf8574.h lcd-buffer.h slcd.h panel.h one-wire.h futil.h xutil.h pid.h mqtt.h -one-wire.o: thermferm.h statetbl.h one-wire.h xutil.h +one-wire.o: thermferm.h statetbl.h one-wire.h devices.h delay.h futil.h xutil.h panel.o: thermferm.h delay.h lcd-pcf8574.h slcd.h panel.h devices.o: thermferm.h delay.h devices.h rc-switch.h panel.h xutil.h lcd-buffer.o: thermferm.h lcd-buffer.h lcd-pcf8574.h slcd.h panel.h
--- a/thermferm/devices.c Wed Apr 03 19:33:38 2024 +0200 +++ b/thermferm/devices.c Fri Apr 05 16:19:39 2024 +0200 @@ -28,10 +28,10 @@ #include "xutil.h" +int my_devices_shutdown = 0; int my_devices_state = 0; extern sys_config Config; -extern int my_shutdown; extern pthread_mutex_t mutexes[5]; extern w1_list *w1_devices; @@ -314,8 +314,10 @@ if ((write_w1(device->address, (char *)"output", output)) == 0) { syslog(LOG_NOTICE, "DS2413 PIO%c value=%d (%s)", (device->subdevice == 0) ? 'A' : 'B', (value == 0) ? 0 : 1, device->comment); + pthread_mutex_lock(&mutexes[LOCK_DEVICES]); device->value = (value == 0) ? 0 : 1; device->timestamp = time(NULL); + pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); } } } @@ -419,7 +421,8 @@ } if (found == FALSE) { - for (i = 0; i < dev_w1->subdevices; i++) { + subdevices = (strcmp(dev_w1->family, (char *)"3a") == 0) ? 2:1; + for (i = 0; i < subdevices; i++) { ndev = (devices_list *)malloc(sizeof(devices_list)); ndev->next = NULL; ndev->uuid = malloc(37); @@ -714,12 +717,13 @@ void *my_devices_loop(void *threadid) { devices_list *device; + w1_list *dev_w1; #ifdef USE_SIMULATOR simulator_list *simulator; #endif - char *addr = NULL, line1[60], line2[60], *p = NULL; - FILE *fp; - int temp, rc; +// char *addr = NULL, line1[60], line2[60], *p = NULL; +// FILE *fp; + int rc, found; time_t now; my_devices_state = 1; @@ -735,27 +739,27 @@ /* * Set the temperature sensors to 12 bits resolution and write it in EEPROM */ - for (device = Config.devices; device; device = device->next) { - if ((device->type == DEVTYPE_W1) && - ((strncmp(device->address, (char *)"10", 2) == 0) || - (strncmp(device->address, (char *)"22", 2) == 0) || - (strncmp(device->address, (char *)"28", 2) == 0) || - (strncmp(device->address, (char *)"3b", 2) == 0) || - (strncmp(device->address, (char *)"42", 2) == 0))) { - addr = xstrcpy((char *)"/sys/bus/w1/devices/"); - addr = xstrcat(addr, device->address); - addr = xstrcat(addr, (char *)"/w1_slave"); - if ((fp = fopen(addr, "w"))) { - rc = fprintf(fp, "12\n0\n"); // According to the kernel documentation. Seems to work. - fclose(fp); - if (rc != 5) { - syslog(LOG_NOTICE, "Program 12 bits resolution error rc=%d for %s", rc, addr); - } - } - free(addr); - addr = NULL; - } - } +// for (device = Config.devices; device; device = device->next) { +// if ((device->type == DEVTYPE_W1) && +// ((strncmp(device->address, (char *)"10", 2) == 0) || + // (strncmp(device->address, (char *)"22", 2) == 0) || +// (strncmp(device->address, (char *)"28", 2) == 0) || +// (strncmp(device->address, (char *)"3b", 2) == 0) || +// (strncmp(device->address, (char *)"42", 2) == 0))) { +// addr = xstrcpy((char *)"/sys/bus/w1/devices/"); +// addr = xstrcat(addr, device->address); +// addr = xstrcat(addr, (char *)"/w1_slave"); +// if ((fp = fopen(addr, "w"))) { +// rc = fprintf(fp, "12\n0\n"); // According to the kernel documentation. Seems to work. +// fclose(fp); +// if (rc != 5) { +// syslog(LOG_NOTICE, "Program 12 bits resolution error rc=%d for %s", rc, addr); +// } +// } +// free(addr); +// addr = NULL; +// } +// } /* * Loop forever until the external shutdown variable is set. @@ -767,7 +771,7 @@ */ for (device = Config.devices; device; device = device->next) { - if (my_shutdown) + if (my_devices_shutdown) break; switch (device->type) { @@ -781,51 +785,23 @@ (strncmp(device->address, (char *)"28", 2) == 0) || (strncmp(device->address, (char *)"3b", 2) == 0) || (strncmp(device->address, (char *)"42", 2) == 0)) { - addr = xstrcpy((char *)"/sys/bus/w1/devices/"); - addr = xstrcat(addr, device->address); - addr = xstrcat(addr, (char *)"/w1_slave"); - if ((fp = fopen(addr, "r"))) { - fgets(line1, 50, fp); // Read 2 lines - fgets(line2, 50, fp); - fclose(fp); - /* - * The output looks like: - * 72 01 4b 46 7f ff 0e 10 57 : crc=57 YES - * 72 01 4b 46 7f ff 0e 10 57 t=23125 - */ - line1[strlen(line1)-1] = '\0'; - if ((line1[36] == 'Y') && (line1[37] == 'E')) { - /* CRC is Ok, continue */ - if (device->present != DEVPRESENT_YES) { - syslog(LOG_NOTICE, "sensor %s is Ok", device->address); - pthread_mutex_lock(&mutexes[LOCK_DEVICES]); + found = FALSE; + for (dev_w1 = w1_devices; dev_w1; dev_w1 = dev_w1->next) { + if (strcmp(device->address, dev_w1->address) == 0) { + syslog(LOG_NOTICE, "sensor %s value %d", dev_w1->address, dev_w1->value); + found = TRUE; + if ((dev_w1->value == -1) || (dev_w1->value < -55000)) { + syslog(LOG_NOTICE, "sensor %s value error %d", device->address, dev_w1->value); + device->present = DEVPRESENT_ERROR; + } else { + device->value = dev_w1->value; + device->timestamp = time(NULL); device->present = DEVPRESENT_YES; - pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); } + } + } - line2[strlen(line2)-1] = '\0'; - strtok(line2, (char *)"="); - p = strtok(NULL, (char *)"="); - rc = sscanf(p, "%d", &temp); - if ((rc == 1) && (device->value != temp)) { - pthread_mutex_lock(&mutexes[LOCK_DEVICES]); - if (temp < -55000) { - syslog(LOG_NOTICE, "sensor %s value error '%d` '%s`", device->address, temp, line1); - device->present = DEVPRESENT_ERROR; - } else { - device->value = temp; - device->timestamp = time(NULL); - device->present = DEVPRESENT_YES; - } - pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); - } - } else { - syslog(LOG_NOTICE, "sensor %s CRC error '%s`", device->address, line1); - pthread_mutex_lock(&mutexes[LOCK_DEVICES]); - device->present = DEVPRESENT_ERROR; - pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); - } - } else { + if (found == FALSE) { if (device->present != DEVPRESENT_NO) { syslog(LOG_NOTICE, "sensor %s is missing", device->address); pthread_mutex_lock(&mutexes[LOCK_DEVICES]); @@ -833,8 +809,7 @@ pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); } } - free(addr); - addr = NULL; + } /* if temperature sensor */ break; @@ -914,12 +889,14 @@ break; } + if (my_devices_shutdown) + break; /* * Delay a bit after procesing a device. */ mDelay(10); } - if (my_shutdown) + if (my_devices_shutdown) break; /* * Delay a bit after all devices
--- a/thermferm/one-wire.c Wed Apr 03 19:33:38 2024 +0200 +++ b/thermferm/one-wire.c Fri Apr 05 16:19:39 2024 +0200 @@ -28,12 +28,14 @@ #include "futil.h" #include "xutil.h" +#define W1_TEMP_RESOLUTION 12 + extern sys_config Config; -extern int my_shutdown; extern pthread_mutex_t mutexes[5]; int my_one_wire_state = 0; +int my_one_wire_shutdown = 0; w1_list *w1_devices = NULL; @@ -66,17 +68,17 @@ ScanNew, ScanDel, Read2413, - Reading, + ReadTemp, Missing SM_NAMES (char *)"ScanNew", (char *)"ScanDel", (char *)"Read2413", - (char *)"Reading", + (char *)"ReadTemp", (char *)"Missing" SM_EDECL - int found, i, rc; + int found, i, rc, value, conv_time; FILE *fp; devices_list *device; w1_list *dev_w1, *n_w1, *cur_w1 = NULL; @@ -87,7 +89,7 @@ SM_STATE(ScanNew) - if (my_shutdown) { + if (my_one_wire_shutdown) { SM_SUCCESS; } @@ -122,9 +124,9 @@ pthread_mutex_unlock(&mutexes[LOCK_ONE_WIRE]); for (device = Config.devices; device; device = device->next) { if (strcmp(dev_w1->address, device->address) == 0) { - pthread_mutex_lock(&mutexes[LOCK_DEVICES]); +// pthread_mutex_lock(&mutexes[LOCK_DEVICES]); device->present = DEVPRESENT_YES; - pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); +// pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); } } } @@ -139,7 +141,8 @@ strncpy(n_w1->family, buffer, 2); n_w1->family[2] = '\0'; n_w1->present = DEVPRESENT_YES; - n_w1->subdevices = (strcmp(w1type, (char *)"3a") == 0) ? 2:1; + n_w1->value = (strcmp(w1type, (char *)"3a") == 0) ? 3:-1; +// n_w1->subdevices = (strcmp(w1type, (char *)"3a") == 0) ? 2:1; n_w1->timestamp = time(NULL); pthread_mutex_lock(&mutexes[LOCK_ONE_WIRE]); @@ -165,7 +168,7 @@ SM_STATE(ScanDel) - if (my_shutdown) { + if (my_one_wire_shutdown) { SM_SUCCESS; } @@ -192,19 +195,21 @@ } } } + free(devfile); + devfile = NULL; } SM_PROCEED(Read2413); SM_STATE(Read2413) - if (my_shutdown) { + if (my_one_wire_shutdown) { SM_SUCCESS; } for (dev_w1 = w1_devices; dev_w1; dev_w1 = dev_w1->next) { if (strcmp(dev_w1->family, "3a") == 0) { - syslog(LOG_NOTICE, "ds2413 %s", dev_w1->address); +// syslog(LOG_NOTICE, "ds2413 %s", dev_w1->address); for (i = 0; i < 2; i++) { for (device = Config.devices; device; device = device->next) { if ((strcmp(dev_w1->address, device->address) == 0) && (device->subdevice == i) && (device->direction == DEVDIR_IN_BIN)) { @@ -216,7 +221,7 @@ state = (unsigned int)rc; output = ((state & 0x02) >> 1) + ((state & 0x08) >> 2); /* Both latch states */ if ((i == 0) && ((state & 0x02) == 0)) { /* Fix A side */ - syslog(LOG_NOTICE, "One-wire device %s-%d out %04x -> %04x", dev_w1->address, i, output, output | 0x01); + syslog(LOG_NOTICE, "One-wire device %s-%d out %02x -> %02x", dev_w1->address, i, output, output | 0x01); output |= 0x01; write_w1(device->address, (char *)"output", output); mDelay(10); @@ -224,7 +229,7 @@ state = (unsigned int)rc; } if ((i == 1) && ((state & 0x08) == 0)) { /* Fix B side */ - syslog(LOG_NOTICE, "One-wire device %s-%d out %04x -> %04x", dev_w1->address, i, output, output | 0x02); + syslog(LOG_NOTICE, "One-wire device %s-%d out %02x -> %02x", dev_w1->address, i, output, output | 0x02); output |= 0x02; write_w1(device->address, (char *)"output", output); mDelay(10); @@ -232,16 +237,19 @@ state = (unsigned int)rc; } - pthread_mutex_lock(&mutexes[LOCK_DEVICES]); + dev_w1->value = ((state & 0x04) >> 1) + (state & 0x01); + syslog(LOG_NOTICE, "One-wire device %s-%d in %02x value %d", dev_w1->address, i, state, dev_w1->value); + +// pthread_mutex_lock(&mutexes[LOCK_DEVICES]); /* * Read PIOA or PIOB pin state bits */ if (device->subdevice == 0) - device->value = (rc & 0x01) ? 0 : 1; + device->value = (state & 0x01) ? 0 : 1; else if (device->subdevice == 1) - device->value = (rc & 0x04) ? 0 : 1; + device->value = (state & 0x04) ? 0 : 1; device->timestamp = time(NULL); - pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); +// pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); } mDelay(20); } @@ -250,11 +258,11 @@ } } - SM_PROCEED(Reading); + SM_PROCEED(ReadTemp); -SM_STATE(Reading) +SM_STATE(ReadTemp) - if (my_shutdown) { + if (my_one_wire_shutdown) { SM_SUCCESS; } @@ -265,17 +273,80 @@ if ((strcmp(cur_w1->family, (char *)"10") == 0) || (strcmp(cur_w1->family, (char *)"22") == 0) || (strcmp(cur_w1->family, (char *)"28") == 0) || (strcmp(cur_w1->family, (char *)"3b") == 0) || (strcmp(cur_w1->family, (char *)"42") == 0)) { - syslog(LOG_NOTICE, "Reading %s", cur_w1->address); - sleep(1); +// syslog(LOG_NOTICE, "Reading %s", cur_w1->address); + /* + * 1. Read sensor resolution. This is a present check too. + * 2. Fix resolution if wrong. + * 3. Read conversion time. + * 4. Open temperature for read. + * 5. Wait conversion time. + * 6. Read temperature. + */ + devfile = xstrcpy((char *)"/sys/bus/w1/devices/"); + devfile = xstrcat(devfile, cur_w1->address); + devfile = xstrcat(devfile, (char *)"/resolution"); + if ((fp = fopen(devfile, "r+"))) { + if ((fgets(buffer, 25, fp))) { + sscanf(buffer, "%d", &value); + if (value != W1_TEMP_RESOLUTION) { + syslog(LOG_NOTICE, "One-wire device %s set resolution from %d to %d", cur_w1->address, value, W1_TEMP_RESOLUTION); + fseek(fp, 0L, SEEK_SET); + sprintf(buffer, "%d", W1_TEMP_RESOLUTION); + fputs(buffer, fp); + } + } + fclose(fp); + free(devfile); + + conv_time = 760; + devfile = xstrcpy((char *)"/sys/bus/w1/devices/"); + devfile = xstrcat(devfile, cur_w1->address); + devfile = xstrcat(devfile, (char *)"/conv_time"); + if ((fp = fopen(devfile, "r"))) { + if ((fgets(buffer, 25, fp))) { + sscanf(buffer, "%d", &conv_time); + } + fclose(fp); + } + free(devfile); + + devfile = xstrcpy((char *)"/sys/bus/w1/devices/"); + devfile = xstrcat(devfile, cur_w1->address); + devfile = xstrcat(devfile, (char *)"/temperature"); + if ((fp = fopen(devfile, "r"))) { + syslog(LOG_NOTICE, "One-wire device %s temperature is open, delay %d", cur_w1->address, conv_time); + mDelay(conv_time); + if ((fgets(buffer, 25, fp))) { + sscanf(buffer, "%d", &value); + syslog(LOG_NOTICE, "One-wire device %s temperature read %d", cur_w1->address, value); + cur_w1->value = value; /* devices.c will pick this up */ + } else { + syslog(LOG_NOTICE, "One-wire device %s temperature read error", cur_w1->address); + } + fclose(fp); + } + + } else { + syslog(LOG_NOTICE, "One-wire device %s open: %s", cur_w1->address, strerror(errno)); + } + free(devfile); + devfile = NULL; } - if (cur_w1->next != NULL) { - cur_w1 = cur_w1->next; - } else { - cur_w1 = w1_devices; + for (;;) { + if (cur_w1->next != NULL) { + cur_w1 = cur_w1->next; + } else { + cur_w1 = w1_devices; + } + if ((strcmp(cur_w1->family, (char *)"10") == 0) || (strcmp(cur_w1->family, (char *)"22") == 0) || (strcmp(cur_w1->family, (char *)"28") == 0) || + (strcmp(cur_w1->family, (char *)"3b") == 0) || (strcmp(cur_w1->family, (char *)"42") == 0)) + break; } + syslog(LOG_NOTICE, "One-wire device %s next sensor %s", cur_w1->address, cur_w1->family); } else { + syslog(LOG_NOTICE, "cur_w1 == NULL"); sleep(1); } @@ -283,7 +354,7 @@ SM_STATE(Missing) - if (my_shutdown) { + if (my_one_wire_shutdown) { SM_SUCCESS; }
--- a/thermferm/panel.c Wed Apr 03 19:33:38 2024 +0200 +++ b/thermferm/panel.c Fri Apr 05 16:19:39 2024 +0200 @@ -46,7 +46,6 @@ -extern int my_shutdown; extern int debug; extern int setupmenu; extern uint16_t keys; @@ -55,6 +54,7 @@ extern pthread_mutex_t mutexes[5]; int my_panel_state = 0; +int my_panel_shutdown = 0; int Key_Enter = FALSE; int Key_Enter_Long = FALSE; int Key_Up = FALSE; @@ -123,7 +123,7 @@ * Loop forever until the external shutdown variable is set. */ for (;;) { - if (my_shutdown) + if (my_panel_shutdown) break; #ifdef HAVE_WIRINGPI_H
--- a/thermferm/server.c Wed Apr 03 19:33:38 2024 +0200 +++ b/thermferm/server.c Fri Apr 05 16:19:39 2024 +0200 @@ -30,7 +30,6 @@ #include "mqtt.h" -extern int my_shutdown; extern int debug; extern int run_pause; extern int run_hold; @@ -46,7 +45,8 @@ int my_server_state = 0; /* Thread running state */ -int s; /* connected socket */ +int my_server_shutdown = 0; /* Thread shutdown */ +//int s; /* connected socket */ int ls; /* listen socket */ struct sockaddr_in myaddr_in; /* for local socket address */ @@ -83,7 +83,7 @@ /* * Send message to client */ -int srv_send(const char *format, ...) +int srv_send(int s, const char *format, ...) { char out[SS_BUFSIZE]; va_list va_ptr; @@ -120,7 +120,7 @@ * Return -1 if error, else the number of received * character. \n is line end, ignore \r. */ -int srv_recv(char *buffer) +int srv_recv(int s, char *buffer) { int bytesloaded = 0; ssize_t ret; @@ -304,7 +304,7 @@ * DEVICE GET uuid * DEVICE PUT uuid */ -int cmd_device(char *buf) +int cmd_device(int s, char *buf) { char *opt, *param, *kwd, *val, ibuf[SS_BUFSIZE]; devices_list *device, *tmpd; @@ -315,35 +315,35 @@ opt = strtok(NULL, " \0"); if (opt == NULL) { - srv_send((char *)"501 Subcommand missing"); + srv_send(s, (char *)"501 Subcommand missing"); return 0; } param = strtok(NULL, "\0"); if (strcmp(opt, (char *)"HELP") == 0) { - srv_send((char *)"100 Help text follows:"); - srv_send((char *)"Recognized commands:"); - srv_send((char *)"DEVICE ADD type Add device (RC433/DHT/I2C/SPI)"); - srv_send((char *)"DEVICE DEL uuid Delete device by uuid"); - srv_send((char *)"DEVICE LIST List all devices"); - srv_send((char *)"DEVICE GET uuid Read device by uuid parameters"); - srv_send((char *)"DEVICE PUT uuid Write device by uuid parameters"); - srv_send((char *)"."); + srv_send(s, (char *)"100 Help text follows:"); + srv_send(s, (char *)"Recognized commands:"); + srv_send(s, (char *)"DEVICE ADD type Add device (RC433/DHT/I2C/SPI)"); + srv_send(s, (char *)"DEVICE DEL uuid Delete device by uuid"); + srv_send(s, (char *)"DEVICE LIST List all devices"); + srv_send(s, (char *)"DEVICE GET uuid Read device by uuid parameters"); + srv_send(s, (char *)"DEVICE PUT uuid Write device by uuid parameters"); + srv_send(s, (char *)"."); return 0; } if (strcmp(opt, (char *)"LIST") == 0) { - srv_send((char *)"212 Devices list follows:"); + srv_send(s, (char *)"212 Devices list follows:"); for (device = Config.devices; device; device = device->next) { - srv_send((char *)"%s,%s,%d,%d,%s,%s,%d", device->uuid, device->address, device->subdevice, + srv_send(s, (char *)"%s,%s,%d,%d,%s,%s,%d", device->uuid, device->address, device->subdevice, device->inuse, device->comment, DEVDIR[device->direction], device->value + device->offset); } - srv_send((char *)"."); + srv_send(s, (char *)"."); return 0; } if (param == NULL) { - srv_send((char *)"502 Parameter missing"); + srv_send(s, (char *)"502 Parameter missing"); return 1; } @@ -383,11 +383,11 @@ } pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); syslog(LOG_NOTICE, "Device %s added", device->uuid); - srv_send((char *)"211 Device %s added", device->uuid); + srv_send(s, (char *)"211 Device %s added", device->uuid); return 1; } else { - srv_send((char *)"503 Parameter error"); + srv_send(s, (char *)"503 Parameter error"); return 0; } } @@ -399,10 +399,10 @@ pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); if (rc) { syslog(LOG_NOTICE, "Device %s deleted", param); - srv_send((char *)"211 Device %s deleted", param); + srv_send(s, (char *)"211 Device %s deleted", param); return 1; } else { - srv_send((char *)"440 No such device"); + srv_send(s, (char *)"440 No such device"); return 0; } } @@ -414,24 +414,24 @@ int my_value = device->value; int my_timestamp = (int)device->timestamp; pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); - srv_send((char *)"213 Device record follows:"); - srv_send((char *)"TYPE,%s", DEVTYPE[device->type]); - srv_send((char *)"ADDRESS,%s", device->address); - srv_send((char *)"DIRECTION,%s", DEVDIR[device->direction]); - srv_send((char *)"VALUE,%d", my_value); - srv_send((char *)"OFFSET,%d", device->offset); - srv_send((char *)"PRESENT,%s", DEVPRESENT[device->present]); - srv_send((char *)"SUBDEVICE,%d", device->subdevice); - srv_send((char *)"GPIOPIN,%d", device->gpiopin); - srv_send((char *)"DESCRIPTION,%s", device->description); - srv_send((char *)"INUSE,%d", device->inuse); - srv_send((char *)"COMMENT,%s", device->comment); - srv_send((char *)"TIMESTAMP,%d", my_timestamp); - srv_send((char *)"."); + srv_send(s, (char *)"213 Device record follows:"); + srv_send(s, (char *)"TYPE,%s", DEVTYPE[device->type]); + srv_send(s, (char *)"ADDRESS,%s", device->address); + srv_send(s, (char *)"DIRECTION,%s", DEVDIR[device->direction]); + srv_send(s, (char *)"VALUE,%d", my_value); + srv_send(s, (char *)"OFFSET,%d", device->offset); + srv_send(s, (char *)"PRESENT,%s", DEVPRESENT[device->present]); + srv_send(s, (char *)"SUBDEVICE,%d", device->subdevice); + srv_send(s, (char *)"GPIOPIN,%d", device->gpiopin); + srv_send(s, (char *)"DESCRIPTION,%s", device->description); + srv_send(s, (char *)"INUSE,%d", device->inuse); + srv_send(s, (char *)"COMMENT,%s", device->comment); + srv_send(s, (char *)"TIMESTAMP,%d", my_timestamp); + srv_send(s, (char *)"."); return 0; } } - srv_send((char *)"440 No such device"); + srv_send(s, (char *)"440 No such device"); return 0; } @@ -439,13 +439,13 @@ for (device = Config.devices; device; device = device->next) { if (strcmp(device->uuid, param) == 0) { while (1) { - rlen = srv_recv(ibuf); + rlen = srv_recv(s, ibuf); if (rlen == -1) { return 0; } if (strlen(ibuf)) { if (strcmp(ibuf, (char *)".") == 0) { - srv_send((char *)"219 Accepted Device record"); + srv_send(s, (char *)"219 Accepted Device record"); return 1; } kwd = strtok(ibuf, ",\0"); @@ -559,11 +559,11 @@ } } } - srv_send((char *)"440 No such device"); + srv_send(s, (char *)"440 No such device"); return 0; } - srv_send((char *)"504 Subcommand error"); + srv_send(s, (char *)"504 Subcommand error"); return 0; } @@ -573,7 +573,7 @@ * GLOBAL GET * GLOBAL PUT */ -int cmd_global(char *buf) +int cmd_global(int s, char *buf) { char *opt, *kwd, *val, ibuf[SS_BUFSIZE]; int ival, rlen; @@ -582,53 +582,53 @@ opt = strtok(NULL, "\0"); if (opt == NULL) { - srv_send((char *)"501 Subcommand missing"); + srv_send(s, (char *)"501 Subcommand missing"); return 0; } if (strcmp(opt, (char *)"HELP") == 0) { - srv_send((char *)"100 Help text follows:"); - srv_send((char *)"Recognized commands:"); - srv_send((char *)"GLOBAL GET Get global settings"); - srv_send((char *)"GLOBAL PUT Put global settings"); - srv_send((char *)"."); + srv_send(s, (char *)"100 Help text follows:"); + srv_send(s, (char *)"Recognized commands:"); + srv_send(s, (char *)"GLOBAL GET Get global settings"); + srv_send(s, (char *)"GLOBAL PUT Put global settings"); + srv_send(s, (char *)"."); return 0; } if (strcmp(opt, (char *)"GET") == 0) { - srv_send((char *)"213 Global Settings record follows:"); - srv_send((char *)"RELEASE,%s", VERSION); - srv_send((char *)"NAME,%s", Config.name); - srv_send((char *)"PORT,%d", Config.my_port); - srv_send((char *)"TEMPFORMAT,%c", Config.tempFormat); - srv_send((char *)"TEMP_ADDRESS,%s", Config.temp_address); - srv_send((char *)"TEMP_STATE,%s", TEMPSTATE[Config.temp_state]); - srv_send((char *)"TEMP_VALUE,%.1f", Config.temp_value / 1000.0); - srv_send((char *)"HUM_ADDRESS,%s", Config.hum_address); - srv_send((char *)"HUM_STATE,%s", TEMPSTATE[Config.hum_state]); - srv_send((char *)"HUM_VALUE,%.0f", Config.hum_value / 1000.0); - srv_send((char *)"TEMP_HUM_IDX,%d", Config.temp_hum_idx); - srv_send((char *)"LCD_COLS,%d", Config.lcd_cols); - srv_send((char *)"LCD_ROWS,%d", Config.lcd_rows); - srv_send((char *)"NEXT_UNIT,%d", Config.next_unit); - srv_send((char *)"MQTT_HOST,%s", Config.mqtt_host); - srv_send((char *)"MQTT_PORT,%d", Config.mqtt_port); - srv_send((char *)"MQTT_USER,%s", Config.mqtt_username); - srv_send((char *)"MQTT_PASS,%s", Config.mqtt_password); - srv_send((char *)"."); + srv_send(s, (char *)"213 Global Settings record follows:"); + srv_send(s, (char *)"RELEASE,%s", VERSION); + srv_send(s, (char *)"NAME,%s", Config.name); + srv_send(s, (char *)"PORT,%d", Config.my_port); + srv_send(s, (char *)"TEMPFORMAT,%c", Config.tempFormat); + srv_send(s, (char *)"TEMP_ADDRESS,%s", Config.temp_address); + srv_send(s, (char *)"TEMP_STATE,%s", TEMPSTATE[Config.temp_state]); + srv_send(s, (char *)"TEMP_VALUE,%.1f", Config.temp_value / 1000.0); + srv_send(s, (char *)"HUM_ADDRESS,%s", Config.hum_address); + srv_send(s, (char *)"HUM_STATE,%s", TEMPSTATE[Config.hum_state]); + srv_send(s, (char *)"HUM_VALUE,%.0f", Config.hum_value / 1000.0); + srv_send(s, (char *)"TEMP_HUM_IDX,%d", Config.temp_hum_idx); + srv_send(s, (char *)"LCD_COLS,%d", Config.lcd_cols); + srv_send(s, (char *)"LCD_ROWS,%d", Config.lcd_rows); + srv_send(s, (char *)"NEXT_UNIT,%d", Config.next_unit); + srv_send(s, (char *)"MQTT_HOST,%s", Config.mqtt_host); + srv_send(s, (char *)"MQTT_PORT,%d", Config.mqtt_port); + srv_send(s, (char *)"MQTT_USER,%s", Config.mqtt_username); + srv_send(s, (char *)"MQTT_PASS,%s", Config.mqtt_password); + srv_send(s, (char *)"."); return 0; } if (strcmp(opt, (char *)"PUT") == 0) { int mqtt_reconnect = 0; while (1) { - rlen = srv_recv(ibuf); + rlen = srv_recv(s, ibuf); if (rlen == -1) { return 0; } if (strlen(ibuf)) { if (strcmp(ibuf, (char *)".") == 0) { - srv_send((char *)"219 Accepted Global record"); + srv_send(s, (char *)"219 Accepted Global record"); if (mqtt_reconnect) mqtt_connect(); return 1; @@ -759,7 +759,7 @@ } } - srv_send((char *)"504 Subcommand error"); + srv_send(s, (char *)"504 Subcommand error"); return 0; } @@ -768,7 +768,7 @@ /* * LIST */ -int cmd_list(char *buf) +int cmd_list(int s, char *buf) { char *opt; units_list *unit; @@ -780,22 +780,22 @@ /* * Default, list available units */ - srv_send((char *)"212 Fermenter list follows:"); + srv_send(s, (char *)"212 Fermenter list follows:"); for (unit = Config.units; unit; unit = unit->next) { - srv_send((char *)"%s,%s,%s", unit->uuid, unit->alias, UNITMODE[unit->mode]); + srv_send(s, (char *)"%s,%s,%s", unit->uuid, unit->alias, UNITMODE[unit->mode]); } - srv_send((char *)"."); + srv_send(s, (char *)"."); return 0; } else if (strcmp(opt, (char *)"HELP") == 0) { - srv_send((char *)"100 Help text follows:"); - srv_send((char *)"Recognized commands:"); - srv_send((char *)"LIST List available units"); - srv_send((char *)"."); + srv_send(s, (char *)"100 Help text follows:"); + srv_send(s, (char *)"Recognized commands:"); + srv_send(s, (char *)"LIST List available units"); + srv_send(s, (char *)"."); return 0; } - srv_send((char *)"504 Subcommand error"); + srv_send(s, (char *)"504 Subcommand error"); return 0; } @@ -844,7 +844,7 @@ * SIMULATOR GET uuid * SIMULATOR PUT uuid */ -int cmd_simulator(char *buf) +int cmd_simulator(int s, char *buf) { char *opt, *param, *kwd, *val, ibuf[SS_BUFSIZE]; simulator_list *simulator, *tmps; @@ -856,34 +856,34 @@ opt = strtok(NULL, " \0"); if (opt == NULL) { - srv_send((char *)"501 Subcommand missing"); + srv_send(s, (char *)"501 Subcommand missing"); return 0; } param = strtok(NULL, "\0"); if (strcmp(opt, (char *)"HELP") == 0) { - srv_send((char *)"100 Help text follows:"); - srv_send((char *)"Recognized commands:"); - srv_send((char *)"SIMULATOR ADD name Add a new Simulator with name"); - srv_send((char *)"SIMULATOR DEL uuid Delete Simulator by uuid"); - srv_send((char *)"SIMULATOR LIST List all Simulators"); - srv_send((char *)"SIMULATOR GET uuid Get Simulator record by uuid"); - srv_send((char *)"SIMULATOR PUT uuid Put Simulator record by uuid"); - srv_send((char *)"."); + srv_send(s, (char *)"100 Help text follows:"); + srv_send(s, (char *)"Recognized commands:"); + srv_send(s, (char *)"SIMULATOR ADD name Add a new Simulator with name"); + srv_send(s, (char *)"SIMULATOR DEL uuid Delete Simulator by uuid"); + srv_send(s, (char *)"SIMULATOR LIST List all Simulators"); + srv_send(s, (char *)"SIMULATOR GET uuid Get Simulator record by uuid"); + srv_send(s, (char *)"SIMULATOR PUT uuid Put Simulator record by uuid"); + srv_send(s, (char *)"."); return 0; } if (strcmp(opt, (char *)"LIST") == 0) { - srv_send((char *)"212 Simulators list follows:"); + srv_send(s, (char *)"212 Simulators list follows:"); for (simulator = Config.simulators; simulator; simulator = simulator->next) { - srv_send((char *)"%s,%s", simulator->uuid, simulator->name); + srv_send(s, (char *)"%s,%s", simulator->uuid, simulator->name); } - srv_send((char *)"."); + srv_send(s, (char *)"."); return 0; } if (param == NULL) { - srv_send((char *)"502 Parameter missing"); + srv_send(s, (char *)"502 Parameter missing"); return 0; } @@ -893,7 +893,7 @@ * For now, only one simulator is allowed. */ if (Config.simulators) { - srv_send((char *)"441 Maximum simulators reached"); + srv_send(s, (char *)"441 Maximum simulators reached"); return 0; } @@ -931,7 +931,7 @@ } syslog(LOG_NOTICE, "Simulator %s added", simulator->uuid); - srv_send((char *)"211 Simulator %s added", simulator->uuid); + srv_send(s, (char *)"211 Simulator %s added", simulator->uuid); return 1; } @@ -939,10 +939,10 @@ rc = delete_Simulator(param); if (rc) { syslog(LOG_NOTICE, "Simulator %s deleted", param); - srv_send((char *)"211 Simulator %s deleted", param); + srv_send(s, (char *)"211 Simulator %s deleted", param); return 1; } else { - srv_send((char *)"440 No such simulator"); + srv_send(s, (char *)"440 No such simulator"); return 0; } } @@ -950,29 +950,29 @@ if (strcmp(opt, (char *)"GET") == 0) { for (simulator = Config.simulators; simulator; simulator = simulator->next) { if (strcmp(simulator->uuid, param) == 0) { - srv_send((char *)"213 Simulator record follows:"); - srv_send((char *)"NAME,%s", simulator->name); - srv_send((char *)"VOLUME_AIR,%d", simulator->volume_air); - srv_send((char *)"VOLUME_BEER,%d", simulator->volume_beer); - srv_send((char *)"ROOM_TEMPERATURE,%.1f", simulator->room_temperature); - srv_send((char *)"ROOM_HUMIDITY,%.1f", simulator->room_humidity); - srv_send((char *)"AIR_TEMPERATURE,%.3f", simulator->air_temperature); - srv_send((char *)"BEER_TEMPERATURE,%.3f", simulator->beer_temperature); - srv_send((char *)"CHILLER_TEMPERATURE,%.3f", simulator->chiller_temperature); - srv_send((char *)"COOLER_TEMP,%.1f", simulator->cooler_temp); - srv_send((char *)"COOLER_TIME,%d", simulator->cooler_time); - srv_send((char *)"COOLER_SIZE,%.3f", simulator->cooler_size); - srv_send((char *)"HEATER_TEMP,%.1f", simulator->heater_temp); - srv_send((char *)"HEATER_TIME,%d", simulator->heater_time); - srv_send((char *)"HEATER_SIZE,%.3f", simulator->heater_size); - srv_send((char *)"HEATER_STATE,%d", simulator->heater_state); - srv_send((char *)"COOLER_STATE,%d", simulator->cooler_state); - srv_send((char *)"FRIGO_ISOLATION,%.3f", simulator->frigo_isolation); - srv_send((char *)"."); + srv_send(s, (char *)"213 Simulator record follows:"); + srv_send(s, (char *)"NAME,%s", simulator->name); + srv_send(s, (char *)"VOLUME_AIR,%d", simulator->volume_air); + srv_send(s, (char *)"VOLUME_BEER,%d", simulator->volume_beer); + srv_send(s, (char *)"ROOM_TEMPERATURE,%.1f", simulator->room_temperature); + srv_send(s, (char *)"ROOM_HUMIDITY,%.1f", simulator->room_humidity); + srv_send(s, (char *)"AIR_TEMPERATURE,%.3f", simulator->air_temperature); + srv_send(s, (char *)"BEER_TEMPERATURE,%.3f", simulator->beer_temperature); + srv_send(s, (char *)"CHILLER_TEMPERATURE,%.3f", simulator->chiller_temperature); + srv_send(s, (char *)"COOLER_TEMP,%.1f", simulator->cooler_temp); + srv_send(s, (char *)"COOLER_TIME,%d", simulator->cooler_time); + srv_send(s, (char *)"COOLER_SIZE,%.3f", simulator->cooler_size); + srv_send(s, (char *)"HEATER_TEMP,%.1f", simulator->heater_temp); + srv_send(s, (char *)"HEATER_TIME,%d", simulator->heater_time); + srv_send(s, (char *)"HEATER_SIZE,%.3f", simulator->heater_size); + srv_send(s, (char *)"HEATER_STATE,%d", simulator->heater_state); + srv_send(s, (char *)"COOLER_STATE,%d", simulator->cooler_state); + srv_send(s, (char *)"FRIGO_ISOLATION,%.3f", simulator->frigo_isolation); + srv_send(s, (char *)"."); return 0; } } - srv_send((char *)"440 No such simulator"); + srv_send(s, (char *)"440 No such simulator"); return 0; } @@ -980,13 +980,13 @@ for (simulator = Config.simulators; simulator; simulator = simulator->next) { if (strcmp(simulator->uuid, param) == 0) { while (1) { - rlen = srv_recv(ibuf); + rlen = srv_recv(s, ibuf); if (rlen == -1) { return 0; } if (strlen(ibuf)) { if (strcmp(ibuf, (char *)".") == 0) { - srv_send((char *)"219 Accepted Simulator record"); + srv_send(s, (char *)"219 Accepted Simulator record"); return 1; } kwd = strtok(ibuf, ",\0"); @@ -1119,11 +1119,11 @@ } } } - srv_send((char *)"440 No such simulator"); + srv_send(s, (char *)"440 No such simulator"); return 0; } - srv_send((char *)"504 Subcommand error"); + srv_send(s, (char *)"504 Subcommand error"); return 0; } #endif @@ -1285,7 +1285,7 @@ * UNIT GET uuid * UNIT PUT uuid */ -int cmd_unit(char *buf) +int cmd_unit(int s, char *buf) { char *opt, *param = NULL, *kwd, *val, ibuf[SS_BUFSIZE]; units_list *unit, *tmpu; @@ -1297,38 +1297,38 @@ opt = strtok(NULL, " \0"); if (opt == NULL) { - srv_send((char *)"501 Subcommand missing"); + srv_send(s, (char *)"501 Subcommand missing"); return 0; } param = strtok(NULL, "\0"); if (strcmp(opt, (char *)"HELP") == 0) { - srv_send((char *)"100 Help text follows:"); - srv_send((char *)"Recognized commands:"); - srv_send((char *)"UNIT ADD name Add a new Unit with name"); - srv_send((char *)"UNIT DEL uuid Delete Unit by uuid"); - srv_send((char *)"UNIT LIST List all Units"); - srv_send((char *)"UNIT GET uuid Get Unit record by uuid"); - srv_send((char *)"UNIT PUT uuid Put Unit record by uuid"); - srv_send((char *)"."); + srv_send(s, (char *)"100 Help text follows:"); + srv_send(s, (char *)"Recognized commands:"); + srv_send(s, (char *)"UNIT ADD name Add a new Unit with name"); + srv_send(s, (char *)"UNIT DEL uuid Delete Unit by uuid"); + srv_send(s, (char *)"UNIT LIST List all Units"); + srv_send(s, (char *)"UNIT GET uuid Get Unit record by uuid"); + srv_send(s, (char *)"UNIT PUT uuid Put Unit record by uuid"); + srv_send(s, (char *)"."); return 0; } if ((strcmp(opt, (char *)"LIST") == 0) && (param == NULL)) { - srv_send((char *)"212 Fermenter list follows:"); + srv_send(s, (char *)"212 Fermenter list follows:"); for (unit = Config.units; unit; unit = unit->next) { if (strlen(unit->product_code) && strlen(unit->product_name)) { - srv_send((char *)"%s,%s %s,%s", unit->uuid, unit->product_code, unit->product_name, UNITMODE[unit->mode]); + srv_send(s, (char *)"%s,%s %s,%s", unit->uuid, unit->product_code, unit->product_name, UNITMODE[unit->mode]); } else { - srv_send((char *)"%s,%s,%s", unit->uuid, unit->alias, UNITMODE[unit->mode]); + srv_send(s, (char *)"%s,%s,%s", unit->uuid, unit->alias, UNITMODE[unit->mode]); } } - srv_send((char *)"."); + srv_send(s, (char *)"."); return 0; } if (param == NULL) { - srv_send((char *)"502 Parameter missing"); + srv_send(s, (char *)"502 Parameter missing"); return 0; } @@ -1396,7 +1396,7 @@ run_pause = FALSE; syslog(LOG_NOTICE, "Unit %s added", unit->uuid); - srv_send((char *)"211 Unit %s added", unit->uuid); + srv_send(s, (char *)"211 Unit %s added", unit->uuid); return 1; } @@ -1417,10 +1417,10 @@ if (rc) { syslog(LOG_NOTICE, "Unit %s deleted", param); - srv_send((char *)"211 Unit %s deleted", param); + srv_send(s, (char *)"211 Unit %s deleted", param); return 1; } else { - srv_send((char *)"440 No such unit"); + srv_send(s, (char *)"440 No such unit"); return 0; } } @@ -1428,102 +1428,102 @@ if (strcmp(opt, (char *)"GET") == 0) { for (unit = Config.units; unit; unit = unit->next) { if (strcmp(param, unit->uuid) == 0) { - srv_send((char *)"213 Unit listing follows:"); - srv_send((char *)"UUID,%s", unit->uuid); - srv_send((char *)"ALIAS,%s", unit->alias); - srv_send((char *)"PRODUCT_NAME,%s", unit->product_name); - srv_send((char *)"PRODUCT_CODE,%s", unit->product_code); - srv_send((char *)"MODE,%s", UNITMODE[unit->mode]); - srv_send((char *)"STAGE,%s", UNITSTAGE[unit->stage]); - srv_send((char *)"VOLUME,%2f", unit->volume); - srv_send((char *)"AIR_ADDRESS,%s", unit->air_address); - srv_send((char *)"AIR_STATE,%s", TEMPSTATE[unit->air_state]); - srv_send((char *)"AIR_TEMPERATURE,%.3f", unit->air_temperature / 1000.0); - srv_send((char *)"AIR_IDX,%d", unit->air_idx); - srv_send((char *)"BEER_ADDRESS,%s", MBSE_SS(unit->beer_address)); - srv_send((char *)"BEER_ADDRESS2,%s", MBSE_SS(unit->beer_address2)); - srv_send((char *)"BEER_STATE,%s", TEMPSTATE[unit->beer_state]); - srv_send((char *)"BEER_TEMPERATURE,%.3f", unit->beer_temperature / 1000.0); - srv_send((char *)"BEER_IDX,%d", unit->beer_idx); - srv_send((char *)"CHILLER_ADDRESS,%s", MBSE_SS(unit->chiller_address)); - srv_send((char *)"CHILLER_STATE,%s", TEMPSTATE[unit->chiller_state]); - srv_send((char *)"CHILLER_TEMPERATURE,%.3f", unit->chiller_temperature / 1000.0); - srv_send((char *)"CHILLER_IDX,%d", unit->chiller_idx); - srv_send((char *)"HEATER_ADDRESS,%s", unit->heater_address); - srv_send((char *)"HEATER_STATE,%d", unit->heater_state); - srv_send((char *)"HEATER_DELAY,%d", unit->heater_delay); - srv_send((char *)"HEATER_USAGE,%d", unit->heater_usage); - srv_send((char *)"HEATER_IDX,%d", unit->heater_idx); + srv_send(s, (char *)"213 Unit listing follows:"); + srv_send(s, (char *)"UUID,%s", unit->uuid); + srv_send(s, (char *)"ALIAS,%s", unit->alias); + srv_send(s, (char *)"PRODUCT_NAME,%s", unit->product_name); + srv_send(s, (char *)"PRODUCT_CODE,%s", unit->product_code); + srv_send(s, (char *)"MODE,%s", UNITMODE[unit->mode]); + srv_send(s, (char *)"STAGE,%s", UNITSTAGE[unit->stage]); + srv_send(s, (char *)"VOLUME,%2f", unit->volume); + srv_send(s, (char *)"AIR_ADDRESS,%s", unit->air_address); + srv_send(s, (char *)"AIR_STATE,%s", TEMPSTATE[unit->air_state]); + srv_send(s, (char *)"AIR_TEMPERATURE,%.3f", unit->air_temperature / 1000.0); + srv_send(s, (char *)"AIR_IDX,%d", unit->air_idx); + srv_send(s, (char *)"BEER_ADDRESS,%s", MBSE_SS(unit->beer_address)); + srv_send(s, (char *)"BEER_ADDRESS2,%s", MBSE_SS(unit->beer_address2)); + srv_send(s, (char *)"BEER_STATE,%s", TEMPSTATE[unit->beer_state]); + srv_send(s, (char *)"BEER_TEMPERATURE,%.3f", unit->beer_temperature / 1000.0); + srv_send(s, (char *)"BEER_IDX,%d", unit->beer_idx); + srv_send(s, (char *)"CHILLER_ADDRESS,%s", MBSE_SS(unit->chiller_address)); + srv_send(s, (char *)"CHILLER_STATE,%s", TEMPSTATE[unit->chiller_state]); + srv_send(s, (char *)"CHILLER_TEMPERATURE,%.3f", unit->chiller_temperature / 1000.0); + srv_send(s, (char *)"CHILLER_IDX,%d", unit->chiller_idx); + srv_send(s, (char *)"HEATER_ADDRESS,%s", unit->heater_address); + srv_send(s, (char *)"HEATER_STATE,%d", unit->heater_state); + srv_send(s, (char *)"HEATER_DELAY,%d", unit->heater_delay); + srv_send(s, (char *)"HEATER_USAGE,%d", unit->heater_usage); + srv_send(s, (char *)"HEATER_IDX,%d", unit->heater_idx); if (unit->PID_heat) { - srv_send((char *)"PIDH_IMAX,%.1f", unit->PID_heat->iMax); - srv_send((char *)"PIDH_IDLERANGE,%.2f", unit->PID_heat->idleRange); - srv_send((char *)"PIDH_PGAIN,%.3f", unit->PID_heat->pGain); - srv_send((char *)"PIDH_IGAIN,%.3f", unit->PID_heat->iGain); - srv_send((char *)"PIDH_DGAIN,%.3f", unit->PID_heat->dGain); - srv_send((char *)"PIDH_SV,%.2f", unit->PID_heat->SetP); + srv_send(s, (char *)"PIDH_IMAX,%.1f", unit->PID_heat->iMax); + srv_send(s, (char *)"PIDH_IDLERANGE,%.2f", unit->PID_heat->idleRange); + srv_send(s, (char *)"PIDH_PGAIN,%.3f", unit->PID_heat->pGain); + srv_send(s, (char *)"PIDH_IGAIN,%.3f", unit->PID_heat->iGain); + srv_send(s, (char *)"PIDH_DGAIN,%.3f", unit->PID_heat->dGain); + srv_send(s, (char *)"PIDH_SV,%.2f", unit->PID_heat->SetP); } - srv_send((char *)"COOLER_ADDRESS,%s", unit->cooler_address); - srv_send((char *)"COOLER_STATE,%d", unit->cooler_state); - srv_send((char *)"COOLER_DELAY,%d", unit->cooler_delay); - srv_send((char *)"COOLER_USAGE,%d", unit->cooler_usage); - srv_send((char *)"COOLER_IDX,%d", unit->cooler_idx); + srv_send(s, (char *)"COOLER_ADDRESS,%s", unit->cooler_address); + srv_send(s, (char *)"COOLER_STATE,%d", unit->cooler_state); + srv_send(s, (char *)"COOLER_DELAY,%d", unit->cooler_delay); + srv_send(s, (char *)"COOLER_USAGE,%d", unit->cooler_usage); + srv_send(s, (char *)"COOLER_IDX,%d", unit->cooler_idx); if (unit->PID_cool) { - srv_send((char *)"PIDC_IMAX,%.1f", unit->PID_cool->iMax); - srv_send((char *)"PIDC_IDLERANGE,%.2f", unit->PID_cool->idleRange); - srv_send((char *)"PIDC_PGAIN,%.3f", unit->PID_cool->pGain); - srv_send((char *)"PIDC_IGAIN,%.3f", unit->PID_cool->iGain); - srv_send((char *)"PIDC_DGAIN,%.3f", unit->PID_cool->dGain); - srv_send((char *)"PIDC_SV,%.2f", unit->PID_cool->SetP); + srv_send(s, (char *)"PIDC_IMAX,%.1f", unit->PID_cool->iMax); + srv_send(s, (char *)"PIDC_IDLERANGE,%.2f", unit->PID_cool->idleRange); + srv_send(s, (char *)"PIDC_PGAIN,%.3f", unit->PID_cool->pGain); + srv_send(s, (char *)"PIDC_IGAIN,%.3f", unit->PID_cool->iGain); + srv_send(s, (char *)"PIDC_DGAIN,%.3f", unit->PID_cool->dGain); + srv_send(s, (char *)"PIDC_SV,%.2f", unit->PID_cool->SetP); } - srv_send((char *)"FAN_ADDRESS,%s", unit->fan_address); - srv_send((char *)"FAN_STATE,%d", unit->fan_state); - srv_send((char *)"FAN_DELAY,%d", unit->fan_delay); - srv_send((char *)"FAN_USAGE,%d", unit->fan_usage); - srv_send((char *)"FAN_IDX,%d", unit->fan_idx); - srv_send((char *)"LIGHT_ADDRESS,%s", unit->light_address); - srv_send((char *)"LIGHT_STATE,%d", unit->light_state); - srv_send((char *)"LIGHT_DELAY,%d", unit->light_delay); - srv_send((char *)"LIGHT_USAGE,%d", unit->light_usage); - srv_send((char *)"LIGHT_IDX,%d", unit->light_idx); - srv_send((char *)"DOOR_ADDRESS,%s", unit->door_address); - srv_send((char *)"DOOR_STATE,%d", unit->door_state); - srv_send((char *)"DOOR_IDX,%d", unit->door_idx); - srv_send((char *)"PSU_ADDRESS,%s", unit->psu_address); - srv_send((char *)"PSU_STATE,%d", unit->psu_state); - srv_send((char *)"PSU_IDX,%d", unit->psu_idx); - srv_send((char *)"FRIDGE_SET_LO,%.1f", unit->fridge_set_lo); - srv_send((char *)"FRIDGE_SET_HI,%.1f", unit->fridge_set_hi); - srv_send((char *)"BEER_SET_LO,%.1f", unit->beer_set_lo); - srv_send((char *)"BEER_SET_HI,%.1f", unit->beer_set_hi); + srv_send(s, (char *)"FAN_ADDRESS,%s", unit->fan_address); + srv_send(s, (char *)"FAN_STATE,%d", unit->fan_state); + srv_send(s, (char *)"FAN_DELAY,%d", unit->fan_delay); + srv_send(s, (char *)"FAN_USAGE,%d", unit->fan_usage); + srv_send(s, (char *)"FAN_IDX,%d", unit->fan_idx); + srv_send(s, (char *)"LIGHT_ADDRESS,%s", unit->light_address); + srv_send(s, (char *)"LIGHT_STATE,%d", unit->light_state); + srv_send(s, (char *)"LIGHT_DELAY,%d", unit->light_delay); + srv_send(s, (char *)"LIGHT_USAGE,%d", unit->light_usage); + srv_send(s, (char *)"LIGHT_IDX,%d", unit->light_idx); + srv_send(s, (char *)"DOOR_ADDRESS,%s", unit->door_address); + srv_send(s, (char *)"DOOR_STATE,%d", unit->door_state); + srv_send(s, (char *)"DOOR_IDX,%d", unit->door_idx); + srv_send(s, (char *)"PSU_ADDRESS,%s", unit->psu_address); + srv_send(s, (char *)"PSU_STATE,%d", unit->psu_state); + srv_send(s, (char *)"PSU_IDX,%d", unit->psu_idx); + srv_send(s, (char *)"FRIDGE_SET_LO,%.1f", unit->fridge_set_lo); + srv_send(s, (char *)"FRIDGE_SET_HI,%.1f", unit->fridge_set_hi); + srv_send(s, (char *)"BEER_SET_LO,%.1f", unit->beer_set_lo); + srv_send(s, (char *)"BEER_SET_HI,%.1f", unit->beer_set_hi); if (unit->profile_uuid) { - srv_send((char *)"PROFILE_UUID,%s", unit->profile_uuid); - srv_send((char *)"PROFILE_NAME,%s", unit->profile_name); - srv_send((char *)"PROFILE_INITTEMP_LO,%.1f", unit->profile_inittemp_lo); - srv_send((char *)"PROFILE_INITTEMP_HI,%.1f", unit->profile_inittemp_hi); - srv_send((char *)"PROFILE_FRIDGE_MODE,%d", unit->profile_fridge_mode); - srv_send((char *)"PROFILE_DURATION,%d", unit->profile_duration); - srv_send((char *)"PROFILE_TOTALSTEPS,%d", unit->profile_totalsteps); - srv_send((char *)"PROF_STARTED,%d", (int)unit->prof_started); + srv_send(s, (char *)"PROFILE_UUID,%s", unit->profile_uuid); + srv_send(s, (char *)"PROFILE_NAME,%s", unit->profile_name); + srv_send(s, (char *)"PROFILE_INITTEMP_LO,%.1f", unit->profile_inittemp_lo); + srv_send(s, (char *)"PROFILE_INITTEMP_HI,%.1f", unit->profile_inittemp_hi); + srv_send(s, (char *)"PROFILE_FRIDGE_MODE,%d", unit->profile_fridge_mode); + srv_send(s, (char *)"PROFILE_DURATION,%d", unit->profile_duration); + srv_send(s, (char *)"PROFILE_TOTALSTEPS,%d", unit->profile_totalsteps); + srv_send(s, (char *)"PROF_STARTED,%d", (int)unit->prof_started); if (unit->prof_state == PROFILE_RUN) { - srv_send((char *)"PROF_STATE,%s %d%%", PROFSTATE[unit->prof_state], unit->prof_percent); + srv_send(s, (char *)"PROF_STATE,%s %d%%", PROFSTATE[unit->prof_state], unit->prof_percent); } else { - srv_send((char *)"PROF_STATE,%s", PROFSTATE[unit->prof_state]); + srv_send(s, (char *)"PROF_STATE,%s", PROFSTATE[unit->prof_state]); } - srv_send((char *)"PROF_TARGET_LO,%.3f", unit->prof_target_lo); - srv_send((char *)"PROF_TARGET_HI,%.3f", unit->prof_target_hi); - srv_send((char *)"PROF_FRIDGE_MODE,%d", unit->prof_fridge_mode); - srv_send((char *)"PROF_PEAK_ABS,%.3f", unit->prof_peak_abs); - srv_send((char *)"PROF_PEAK_REL,%.3f", unit->prof_peak_rel); - srv_send((char *)"PROF_PRIMARY_DONE,%d", (int)unit->prof_primary_done); + srv_send(s, (char *)"PROF_TARGET_LO,%.3f", unit->prof_target_lo); + srv_send(s, (char *)"PROF_TARGET_HI,%.3f", unit->prof_target_hi); + srv_send(s, (char *)"PROF_FRIDGE_MODE,%d", unit->prof_fridge_mode); + srv_send(s, (char *)"PROF_PEAK_ABS,%.3f", unit->prof_peak_abs); + srv_send(s, (char *)"PROF_PEAK_REL,%.3f", unit->prof_peak_rel); + srv_send(s, (char *)"PROF_PRIMARY_DONE,%d", (int)unit->prof_primary_done); } - srv_send((char *)"TEMP_SET_MIN,%.1f", unit->temp_set_min); - srv_send((char *)"TEMP_SET_MAX,%.1f", unit->temp_set_max); - srv_send((char *)"ALARM,%d", unit->alarm_flag); - srv_send((char *)"."); + srv_send(s, (char *)"TEMP_SET_MIN,%.1f", unit->temp_set_min); + srv_send(s, (char *)"TEMP_SET_MAX,%.1f", unit->temp_set_max); + srv_send(s, (char *)"ALARM,%d", unit->alarm_flag); + srv_send(s, (char *)"."); return 0; } } - srv_send((char *)"440 No such unit"); + srv_send(s, (char *)"440 No such unit"); return 0; } @@ -1542,14 +1542,14 @@ if (strcmp(unit->uuid, param) == 0) { while (1) { unit->mqtt_flag = 0; - rlen = srv_recv(ibuf); + rlen = srv_recv(s, ibuf); if (rlen == -1) { run_pause = FALSE; return 0; } if (strlen(ibuf)) { if (strcmp(ibuf, (char *)".") == 0) { - srv_send((char *)"219 Accepted Unit record"); + srv_send(s, (char *)"219 Accepted Unit record"); run_pause = FALSE; return 1; } @@ -2068,74 +2068,74 @@ } } } - srv_send((char *)"440 No such unit"); + srv_send(s, (char *)"440 No such unit"); run_pause = FALSE; return 0; } - srv_send((char *)"504 Subcommand error"); + srv_send(s, (char *)"504 Subcommand error"); return 0; } -void cmd_server(void) +void cmd_server(int s) { char buf[SS_BUFSIZE]; int rlen; - rlen = srv_recv(buf); + rlen = srv_recv(s, buf); if (rlen != -1) { if (strlen(buf)) { /* * Process commands from the client */ if (strncmp(buf, "DEVICE", 6) == 0) { - if (cmd_device(buf)) + if (cmd_device(s, buf)) wrconfig(); } else if (strncmp(buf, "GLOBAL", 6) == 0) { - if (cmd_global(buf)) + if (cmd_global(s, buf)) wrconfig(); } else if (strncmp(buf, "HELP", 4) == 0) { - srv_send((char *)"100 Help text follows"); - srv_send((char *)"Recognized commands:"); - srv_send((char *)""); + srv_send(s, (char *)"100 Help text follows"); + srv_send(s, (char *)"Recognized commands:"); + srv_send(s, (char *)""); // 12345678901234567890123456789012345678901234567890123456789012345678901234567890 - srv_send((char *)"DEVICE <CMD> [parameters] Device commands"); - srv_send((char *)"DEVICE HELP Device help screen"); - srv_send((char *)"GLOBAL <CMD> [parameters] Global commands"); - srv_send((char *)"GLOBAL HELP Global help screen"); - srv_send((char *)"LIST <CMD> [parameters] List commands"); - srv_send((char *)"LIST HELP List help screen"); - srv_send((char *)"PING Check if server is alive"); + srv_send(s, (char *)"DEVICE <CMD> [parameters] Device commands"); + srv_send(s, (char *)"DEVICE HELP Device help screen"); + srv_send(s, (char *)"GLOBAL <CMD> [parameters] Global commands"); + srv_send(s, (char *)"GLOBAL HELP Global help screen"); + srv_send(s, (char *)"LIST <CMD> [parameters] List commands"); + srv_send(s, (char *)"LIST HELP List help screen"); + srv_send(s, (char *)"PING Check if server is alive"); #ifdef USE_SIMULATOR - srv_send((char *)"SIMULATOR <CMD> [parameters] Simulator commands"); - srv_send((char *)"SIMULATOR HELP Simulator help screen"); + srv_send(s, (char *)"SIMULATOR <CMD> [parameters] Simulator commands"); + srv_send(s, (char *)"SIMULATOR HELP Simulator help screen"); #endif - srv_send((char *)"UNIT <CMD> [parameters] Unit commands"); - srv_send((char *)"UNIT HELP Unit help screen"); - srv_send((char *)"."); + srv_send(s, (char *)"UNIT <CMD> [parameters] Unit commands"); + srv_send(s, (char *)"UNIT HELP Unit help screen"); + srv_send(s, (char *)"."); } else if (strncmp(buf, "LIST", 4) == 0) { - cmd_list(buf); + cmd_list(s, buf); } else if (strncmp(buf, "PING", 4) == 0) { - srv_send((char *)"101 PONG"); + srv_send(s, (char *)"101 PONG"); #ifdef USE_SIMULATOR } else if (strncmp(buf, "SIMULATOR", 9) == 0) { - if (cmd_simulator(buf)) + if (cmd_simulator(s, buf)) wrconfig(); #endif } else if (strncmp(buf, "UNIT", 4) == 0) { - if (cmd_unit(buf)) + if (cmd_unit(s, buf)) wrconfig(); } else { - srv_send((char *)"500 Unknown command"); + srv_send(s, (char *)"500 Unknown command"); } } } @@ -2144,17 +2144,31 @@ } +static void cleanup_handler(void *arg) +{ + syslog(LOG_NOTICE, "Thread my_server_loop stopped (cleanup_handler)"); + close(ls); + my_server_state = 0; +} + void *my_server_loop(void *threadid) { socklen_t addrlen; - int optval = 1; + int s, optval = 1; my_server_state = 1; syslog(LOG_NOTICE, "Thread my_server_loop started"); if (debug) fprintf(stdout, "Thread my_server_loop started\n"); + /* + * Prepare thread to stop in blocking accept() call. + */ + pthread_cleanup_push(cleanup_handler, NULL); + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + memset((char *)&myaddr_in, 0, sizeof(struct sockaddr_in)); memset((char *)&peeraddr_in, 0, sizeof(struct sockaddr_in)); myaddr_in.sin_family = AF_INET; @@ -2176,12 +2190,12 @@ return 0; } - if (setsockopt(ls, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1) { - syslog(LOG_NOTICE, "Can't setsockopt SO_REUSEADDR socket: %s", strerror(errno)); - close(ls); - my_server_state = 0; - return 0; - } +// if (setsockopt(ls, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1) { +// syslog(LOG_NOTICE, "Can't setsockopt SO_REUSEADDR socket: %s", strerror(errno)); +// close(ls); +// my_server_state = 0; +// return 0; +// } if (bind(ls, (struct sockaddr *)&myaddr_in, sizeof(struct sockaddr_in)) == -1) { syslog(LOG_NOTICE, "Can't bind to listen socket: %s", strerror(errno)); @@ -2199,7 +2213,6 @@ syslog(LOG_NOTICE, "listen socket created %d", ls); - /* * Loop forever until the external shutdown variable is set. */ @@ -2213,25 +2226,26 @@ * descriptor, s, for that connection. */ s = accept(ls, (struct sockaddr *)&peeraddr_in, &addrlen); + syslog(LOG_NOTICE, "my_server_loop accept socket %d", s); if (s == -1) { syslog(LOG_NOTICE, "my_server_loop accept failed %s", strerror(errno)); - if (debug) - fprintf(stdout, "my_server_loop accept failed %s\n", strerror(errno)); - my_server_state = 0; - return 0; + break; } - - cmd_server(); + if (my_server_shutdown) + break; - if (my_shutdown) { - syslog(LOG_NOTICE, "Thread my_server_loop stopped"); - if (debug) - fprintf(stdout, "Thread my_server_loop stopped\n"); - my_server_state = 0; - return 0; - } + cmd_server(s); + + if (my_server_shutdown) + break; mDelay(100); } + + close(ls); + pthread_cleanup_pop(my_server_state); + syslog(LOG_NOTICE, "Thread my_server_loop stopped"); + my_server_state = 0; + return 0; }
--- a/thermferm/simulator.c Wed Apr 03 19:33:38 2024 +0200 +++ b/thermferm/simulator.c Fri Apr 05 16:19:39 2024 +0200 @@ -28,9 +28,9 @@ #ifdef USE_SIMULATOR -extern int my_shutdown; extern sys_config Config; +int my_simulator_shutdown = 0; int SIMcooling = 0; int SIMheating = 0; int SIMfan = 0; @@ -56,11 +56,11 @@ } for (;;) { - if (my_shutdown) + if (my_simulator_shutdown) break; for (simulator = Config.simulators; simulator; simulator = simulator->next) { - if (my_shutdown) + if (my_simulator_shutdown) break; now = time(NULL);
--- a/thermferm/thermferm.c Wed Apr 03 19:33:38 2024 +0200 +++ b/thermferm/thermferm.c Fri Apr 05 16:19:39 2024 +0200 @@ -49,15 +49,29 @@ extern int lcdHandle; extern int slcdHandle; extern int my_devices_state; +extern int my_devices_shutdown; extern int my_panel_state; +extern int my_panel_shutdown; extern int my_server_state; +extern int my_server_shutdown; extern int my_simulator_state; +#ifdef USE_SIMULATOR +extern int my_simulator_shutdown; +#endif extern int my_one_wire_state; +extern int my_one_wire_shutdown; int setupmenu = MENU_NONE; units_list *current_unit = NULL; /* In panel editor this points to the current unit. */ float temp_temp = 20.0; -pthread_t threads[5]; +pthread_t my_one_wire_thread; +pthread_t my_devices_thread; +pthread_t my_panel_thread; +pthread_t my_server_thread; +#ifdef USE_SIMULATOR +pthread_t my_simulator_thread; +#endif + pthread_mutex_t mutexes[5]; extern const char UNITMODE[5][8]; @@ -1040,13 +1054,13 @@ /* * First scan the one-wire bus */ - rc = pthread_create(&threads[t], NULL, my_one_wire_loop, (void *)t ); + rc = pthread_create(&my_one_wire_thread, NULL, my_one_wire_loop, (void *)t ); if (rc) { fprintf(stderr, "my_one_wire_loop thread didn't start rc=%d\n", rc); syslog(LOG_NOTICE, "my_one_wire_loop thread didn't start rc=%d", rc); } else { t++; - mDelay(250); /* Wait a while to detect the devices */ + mDelay(2500); /* Wait a while to detect the devices */ } if ((rc = devices_detect())) { @@ -1054,7 +1068,7 @@ wrconfig(); } - rc = pthread_create(&threads[t], NULL, my_devices_loop, (void *)t ); + rc = pthread_create(&my_devices_thread, NULL, my_devices_loop, (void *)t ); if (rc) { fprintf(stderr, "my_devices_loop thread didn't start rc=%d\n", rc); syslog(LOG_NOTICE, "my_devices_loop thread didn't start rc=%d", rc); @@ -1062,7 +1076,7 @@ t++; } - rc = pthread_create(&threads[t], NULL, my_server_loop, (void *)t ); + rc = pthread_create(&my_server_thread, NULL, my_server_loop, (void *)t ); if (rc) { fprintf(stderr, "my_server_loop thread didn't start rc=%d\n", rc); syslog(LOG_NOTICE, "my_server_loop thread didn't start rc=%d", rc); @@ -1070,7 +1084,7 @@ t++; } - rc = pthread_create(&threads[t], NULL, my_panel_loop, (void *)t ); + rc = pthread_create(&my_panel_thread, NULL, my_panel_loop, (void *)t ); if (rc) { fprintf(stderr, "my_panel_loop thread didn't start rc=%d\n", rc); syslog(LOG_NOTICE, "my_panel_loop thread didn't start rc=%d", rc); @@ -1079,7 +1093,7 @@ } #ifdef USE_SIMULATOR - rc = pthread_create(&threads[t], NULL, my_simulator_loop, (void *)t ); + rc = pthread_create(&my_simulator_thread, NULL, my_simulator_loop, (void *)t ); if (rc) { fprintf(stderr, "my_simulator_loop thread didn't start rc=%d\n", rc); syslog(LOG_NOTICE, "my_simulator_loop thread didn't start rc=%d", rc); @@ -1925,13 +1939,38 @@ } syslog(LOG_NOTICE, "Unit `%s' stopped in mode %s", unit->alias, UNITMODE[unit->mode]); } - syslog(LOG_NOTICE, "Out of loop"); + syslog(LOG_NOTICE, "Out of loop, stopping threads.."); + + /* + * Stop threads + */ +#ifdef USE_SIMULATOR + my_simulator_shutdown = 1; + while (my_simulator_state) { mDelay(50); }; +#endif + my_panel_shutdown = 1; + while (my_panel_state) { mDelay(50); }; /* - * Note that we don't care if the command server is stopped, this one - * does almost certain keep running but that doesn't harm. + * Cancel command and shutdown via variable, one of them + * will stop this thread. Includes a failsafe. */ - while ((my_devices_state + my_panel_state + my_simulator_state + my_one_wire_state) > 0) { sleep(1); }; + my_server_shutdown = 1; + rc = pthread_cancel(my_server_thread); + rc = 0; + while (my_server_state) { + mDelay(50); + if (rc++ > 20) { + syslog(LOG_NOTICE, "Cannot terminate my_server_loop()"); + break; + } + } + + my_devices_shutdown = 1; + while (my_devices_state) { mDelay(50); }; + my_one_wire_shutdown = 1; + while (my_one_wire_state) { mDelay(50); }; + mqtt_disconnect(); stopLCD();
--- a/thermferm/thermferm.h Wed Apr 03 19:33:38 2024 +0200 +++ b/thermferm/thermferm.h Fri Apr 05 16:19:39 2024 +0200 @@ -313,7 +313,8 @@ char *address; ///< Device address char family[3]; ///< Device family int present; ///< Present on bus - int subdevices; ///< Number of subdevices + int value; ///< Last value +// int subdevices; ///< Number of subdevices time_t timestamp; ///< Last seen } w1_list;