# HG changeset patch # User Michiel Broek # Date 1712514397 -7200 # Node ID 48cc8868f9f4ab7cfa5df9be762d174271dca986 # Parent 66fae54fa7baa2a521e1ecfae9c2b19371e7aa34 Added commandline switch --foreground, the --debug now only activates extra debug logging. No more console output. The thermferm process uses a state table, this makes the code more readable and have less large functions. diff -r 66fae54fa7ba -r 48cc8868f9f4 thermferm/mqtt.c --- a/thermferm/mqtt.c Sun Apr 07 16:05:06 2024 +0200 +++ b/thermferm/mqtt.c Sun Apr 07 20:26:37 2024 +0200 @@ -171,7 +171,7 @@ *c = 0 ; if (debug) - fprintf(stdout, "piBoardId: Revision string: %s\n", line) ; + syslog(LOG_NOTICE, "piBoardId: Revision string: %s", line) ; // Need to work out if it's using the new or old encoding scheme: @@ -201,7 +201,7 @@ if ((revision & (1 << 23)) != 0) { // New way if (debug) - fprintf(stdout, "piBoardId: New Way: revision is: %08X\n", revision) ; + syslog(LOG_NOTICE, "piBoardId: New Way: revision is: %08X", revision) ; bRev = (revision & (0x0F << 0)) >> 0 ; bType = (revision & (0xFF << 4)) >> 4 ; @@ -217,10 +217,10 @@ *warranty = bWarranty ; if (debug) - fprintf(stdout, "piBoardId: rev: %d, type: %d, proc: %d, mfg: %d, mem: %d, warranty: %d\n", bRev, bType, bProc, bMfg, bMem, bWarranty) ; + syslog(LOG_NOTICE, "piBoardId: rev: %d, type: %d, proc: %d, mfg: %d, mem: %d, warranty: %d", bRev, bType, bProc, bMfg, bMem, bWarranty) ; } else { // Old way if (debug) - fprintf(stdout, "piBoardId: Old Way: revision is: %s\n", c) ; + syslog(LOG_NOTICE, "piBoardId: Old Way: revision is: %s", c) ; if (!isdigit (*c)) { syslog(LOG_NOTICE, "Bogus \"Revision\" line (no digit at start of revision)") ; @@ -374,7 +374,7 @@ void my_log_callback(struct mosquitto *my_mosq, void *obj, int level, const char *str) { // if (debug) -// fprintf(stdout, "MQTT: %s\n", str); +// syslog(LOG_NOTICE, "MQTT: %s", str); } diff -r 66fae54fa7ba -r 48cc8868f9f4 thermferm/rdconfig.c --- a/thermferm/rdconfig.c Sun Apr 07 16:05:06 2024 +0200 +++ b/thermferm/rdconfig.c Sun Apr 07 20:26:37 2024 +0200 @@ -27,6 +27,7 @@ #include "xutil.h" int debug = FALSE; +int foreground = FALSE; sys_config Config; /* System configuration */ extern pthread_mutex_t mutexes[5]; @@ -481,7 +482,7 @@ mypath = xstrcat(mypath, (char *)"thermferm.xml"); if (debug) - fprintf(stdout, "Writing %s\n", mypath); + syslog(LOG_NOTICE, "Writing %s", mypath); if ((fp = fopen(mypath, "w")) == NULL) { syslog(LOG_NOTICE, "could not rewrite %s", mypath); diff -r 66fae54fa7ba -r 48cc8868f9f4 thermferm/server.c --- a/thermferm/server.c Sun Apr 07 16:05:06 2024 +0200 +++ b/thermferm/server.c Sun Apr 07 20:26:37 2024 +0200 @@ -97,7 +97,6 @@ // if (debug) { // syslog(LOG_NOTICE, "send: \"%s\"", out); -// fprintf(stdout, "send: \"%s\"\n", out); // } if (send(s, out, strlen(out), 0) != strlen(out)) { @@ -153,7 +152,6 @@ // if (debug) { // syslog(LOG_NOTICE, "recv: %d `%s'", bytesloaded, buffer); -// fprintf(stdout, "recv: %d `%s'\n", bytesloaded, buffer); // } return bytesloaded; } @@ -2159,8 +2157,6 @@ 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. diff -r 66fae54fa7ba -r 48cc8868f9f4 thermferm/thermferm.c --- a/thermferm/thermferm.c Sun Apr 07 16:05:06 2024 +0200 +++ b/thermferm/thermferm.c Sun Apr 07 20:26:37 2024 +0200 @@ -47,6 +47,7 @@ int row; extern int debug; +extern int foreground; extern sys_config Config; extern int lcdHandle; extern int slcdHandle; @@ -118,7 +119,8 @@ { fprintf(stdout, "mbsePi-apps thermferm v%s starting\n\n", VERSION); fprintf(stdout, "Usage: thermferm [-d] [-h]\n"); - fprintf(stdout, " -d --debug Debug and run in foreground\n"); + fprintf(stdout, " -d --debug Extra debug logging\n"); + fprintf(stdout, " -f --foreground Run in foreground\n"); fprintf(stdout, " -h --help Display this help\n"); } @@ -891,6 +893,7 @@ int option_index = 0; static struct option long_options[] = { {"debug", 0, 0, 'c'}, + {"foreground", 0, 0, 'f'}, {"help", 0, 0, 'h'}, {0, 0, 0, 0} }; @@ -902,6 +905,8 @@ switch (c) { case 'd': debug = TRUE; break; + case 'f': foreground = TRUE; + break; case 'h': help(); return 1; } @@ -909,8 +914,6 @@ openlog("thermferm", LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_USER); syslog(LOG_NOTICE, "mbsePi-apps thermferm v%s starting", VERSION); - if (debug) - fprintf(stdout, "mbsePi-apps thermferm v%s starting\n", VERSION); if (rdconfig()) { fprintf(stderr, "Error reading configuration\n"); @@ -960,9 +963,9 @@ slcdCharDef(slcdHandle, 5, HeatONOFF); slcdCharDef(slcdHandle, 6, RevHeatONOFF); - if (debug) { + if (foreground) { /* - * For debugging run in foreground. + * Run in foreground. */ do { rc = server(); @@ -1023,13 +1026,11 @@ killconfig(); syslog(LOG_NOTICE, "Finished, rc=%d", rc); - if (debug) - fprintf(stdout, "Finished, rc=%d\n", rc); return rc; } -void do_unit(units_list *unit, int LCDunit, int *seconds, int *minutes) +void do_unit(units_list *unit, int LCDunit, int seconds, int minutes) { time_t now; prof_step *step; @@ -1199,7 +1200,7 @@ run_minutes = run_seconds / 60; run_hours = run_minutes / 60; if (debug) - fprintf(stdout, "run_HMS=%d,%d,%d ", run_hours, run_minutes, run_seconds); + syslog(LOG_NOTICE, "run_HMS=%d,%d,%d", run_hours, run_minutes, run_seconds); /* * Primary fermentation tests @@ -1271,7 +1272,7 @@ unit->prof_fridge_mode = step->fridge_mode; } if (debug) - fprintf(stdout, "prof_fridge_mode=%d run_minutes=%d steptime=%d time_until_now=%d\n", + syslog(LOG_NOTICE, "prof_fridge_mode=%d run_minutes=%d steptime=%d time_until_now=%d", unit->prof_fridge_mode, run_minutes, step->steptime, time_until_now); } else { unit->prof_target_lo = step->target_lo; @@ -1288,7 +1289,7 @@ if (valid_step == TRUE) { unit->prof_percent = (100 * run_minutes) / tot_minutes; - if (((*minutes == 10) || (*minutes == 40)) && (*seconds == 1)) { + if (((minutes == 10) || (minutes == 40)) && (seconds == 1)) { syslog(LOG_NOTICE, "Profile `%s' running %dd %02d:%02d in step %d, %d%% done, fridge/beer %d%% %.3f..%.3f degrees", unit->profile_name, run_hours / 24, run_hours % 24, run_minutes % 60, current_step, unit->prof_percent, unit->prof_fridge_mode, unit->prof_target_lo, unit->prof_target_hi); @@ -1431,7 +1432,7 @@ if ((unit->mode == UNITMODE_BEER) && ((unit->air_temperature / 1000.0) > (unit->PID_heat->Input + 8.0))) { unit->PID_heat->OutP = 0.0; } - if (*seconds == 60) { + if (seconds == 60) { syslog(LOG_NOTICE, "Heat: sp=%.3f Input=%.3f iState=%.3f Err=%.3f Out=%.1f", unit->PID_heat->SetP, unit->PID_heat->Input, unit->PID_heat->iState, unit->PID_heat->Err, unit->PID_heat->OutP); } @@ -1452,12 +1453,12 @@ if ((unit->chiller_temperature / 1000.0) > ((unit->air_temperature / 1000.0) - 1)) { unit->PID_cool->OutP = 0.0; unit->alarm_flag |= ALARM_FLAG_CHILLER; - if (*seconds == 60) { + if (seconds == 60) { syslog(LOG_NOTICE, "Cool: Air=%.2f Chiller=%.2f alarm", unit->air_temperature / 1000.0, unit->chiller_temperature / 1000.0); } } } - if (*seconds == 60) { + if (seconds == 60) { syslog(LOG_NOTICE, "Cool: sp=%.3f Input=%.3f iState=%.3f Err=%.3f Out=%.1f", unit->PID_cool->SetP, unit->PID_cool->Input, unit->PID_cool->iState, unit->PID_cool->Err, unit->PID_cool->OutP); } @@ -1612,7 +1613,7 @@ LCDspH = unit->prof_target_hi; } } - if (*seconds == 60) { + if (seconds == 60) { unit->mqtt_flag |= MQTT_FLAG_DATA; } pthread_mutex_lock(&mutexes[LOCK_LCD]); @@ -1652,16 +1653,229 @@ } +SM_DECL(thermferm,(char *)"thermferm") +SM_STATES + CheckRun, + WaitMinute, + DateTime, + RoomTHB, + Units, + ShowLCD, + Minute, + Keys, + Delay +SM_NAMES + (char *)"CheckRun", + (char *)"WaitMinute", + (char *)"DateTime", + (char *)"RoomTHB", + (char *)"Units", + (char *)"ShowLCD", + (char *)"Minute", + (char *)"Keys", + (char *)"Delay" +SM_EDECL + + time_t now, last = (time_t)0, ndata = (time_t)0; + int key, LCDunit, rc, temp, seconds = 0, minutes = 0; + struct tm *tm; + units_list *unit; + +SM_START(CheckRun) + +SM_STATE(CheckRun) + + if (my_shutdown) { + SM_SUCCESS; + } + + /* + * Use to stop processing units. Should be used when a unit is + * added or removed. + */ + if (run_pause) { + run_hold = TRUE; + syslog(LOG_NOTICE, "run_pause: entering hold state"); + for (;;) { + mDelay(100); + if (! run_pause) + break; + } + syslog(LOG_NOTICE, "run_pause: leaving hold state"); + run_hold = FALSE; + /* + * In case the LCD buffers were cleared, setup the first page. + */ + pthread_mutex_lock(&mutexes[LOCK_LCD]); + lcd_buf_write(1, (char *)" ThermFerm "); + lcd_buf_write(2, (char *)"Version %s ", VERSION); + pthread_mutex_unlock(&mutexes[LOCK_LCD]); + } + SM_PROCEED(WaitMinute); + +SM_STATE(WaitMinute) + + if (my_shutdown) { + SM_SUCCESS; + } + + now = time(NULL); + if (now != last) { + /* + * Each second + */ + last = now; + seconds++; + SM_PROCEED(DateTime); + } else { + SM_PROCEED(Keys); + } + +SM_STATE(DateTime) + + row = 3; + tm = localtime(&now); + pthread_mutex_lock(&mutexes[LOCK_LCD]); + lcd_buf_write(row++, " %02d-%02d-%04d ", tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900); + lcd_buf_write(row++, " %02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec); + pthread_mutex_unlock(&mutexes[LOCK_LCD]); + SM_PROCEED(RoomTHB); + +SM_STATE(RoomTHB) + + pthread_mutex_lock(&mutexes[LOCK_LCD]); + lcd_buf_write(row, "Room temp N/A "); + pthread_mutex_unlock(&mutexes[LOCK_LCD]); + int updateHT = 0; + if (Config.temp_address) { + rc = device_in(Config.temp_address, &temp); + if (rc == DEVPRESENT_YES) { + if (Config.temp_value != temp) + updateHT = 1; + Config.temp_value = temp; + Config.temp_state = 0; + pthread_mutex_lock(&mutexes[LOCK_LCD]); + lcd_buf_write(row, "Room temp %.1f%c ", Config.temp_value / 1000.0, 0x01); + pthread_mutex_unlock(&mutexes[LOCK_LCD]); + } else if (rc == DEVPRESENT_ERROR) { + Config.temp_state = 1; + } else { + Config.temp_state = 2; + } + mDelay(10); + } + row++; + + pthread_mutex_lock(&mutexes[LOCK_LCD]); + lcd_buf_write(row, " Humidity N/A "); + pthread_mutex_unlock(&mutexes[LOCK_LCD]); + if (Config.hum_address) { + rc = device_in(Config.hum_address, &temp); + if (rc == DEVPRESENT_YES) { + if (Config.hum_value != temp) + updateHT = 1; + Config.hum_value = temp; + Config.hum_state = 0; + pthread_mutex_lock(&mutexes[LOCK_LCD]); + lcd_buf_write(row, " Humidity %.1f%% ", Config.hum_value / 1000.0); + pthread_mutex_unlock(&mutexes[LOCK_LCD]); + } else if (rc == DEVPRESENT_ERROR) { + Config.hum_state = 1; + } else { + Config.hum_state = 2; + } + mDelay(10); + } + row++; + + /* + * If TH(B) changed. or if 5 minutes without + * update, send the NDATA message. + */ + if (updateHT || (now > (ndata + 300))) { + publishNData(false, 0); + ndata = now; + } + SM_PROCEED(Units); + +SM_STATE(Units) + + LCDunit = 0; + for (unit = Config.units; unit; unit = unit->next) { + LCDunit++; + do_unit(unit, LCDunit, seconds, minutes); + } + SM_PROCEED(ShowLCD); + +SM_STATE(ShowLCD) + + pthread_mutex_lock(&mutexes[LOCK_MENU]); + if (setupmenu == MENU_NONE) { + pthread_mutex_lock(&mutexes[LOCK_LCD]); + lcd_buf_show(); + pthread_mutex_unlock(&mutexes[LOCK_LCD]); + } + pthread_mutex_unlock(&mutexes[LOCK_MENU]); + SM_PROCEED(Minute); + +SM_STATE(Minute) + + if (seconds == 60) { + seconds = 0; + + /* + * Publish data every minute if unit is active. + */ + for (unit = Config.units; unit; unit = unit->next) { + if (unit->mode != UNITMODE_OFF) { + publishDLog(unit); + if (unit->event_msg) + free(unit->event_msg); + unit->event_msg = NULL; + } + } + + minutes++; + if (minutes == 60) { + minutes = 0; + /* + * Log usage counters every hour + */ + for (unit = Config.units; unit; unit = unit->next) { + syslog(LOG_NOTICE, "Unit `%s' usage heater=%d cooler=%d fan=%d", unit->alias, unit->heater_usage, unit->cooler_usage, unit->fan_usage); + } + } + + /* + * Save the configuration each half hour. + */ + if ((minutes == 15) || (minutes == 45)) + wrconfig(); + } + SM_PROCEED(Keys); + +SM_STATE(Keys) + + slcdDummy(slcdHandle); + key = keycheck(); + if (key != KEY_NONE) + panel_key_events(key); + SM_PROCEED(Delay); + +SM_STATE(Delay) + + mDelay(100); + SM_PROCEED(CheckRun); + +SM_END +SM_RETURN + int server(void) { - time_t now, last = (time_t)0, ndata = (time_t)0;; - units_list *unit; - int rc, run = 1, seconds = 0, minutes = 0, temp; - int key; - struct tm *tm; - long t = 0; - int LCDunit; + units_list *unit; + int rc; + long t = 0; syslog(LOG_NOTICE, "Server process started"); my_shutdown = my_reboot = FALSE; @@ -1766,159 +1980,10 @@ // 0.9.17a2 pthread_mutex_unlock(&mutexes[LOCK_LCD]); - do { - if (my_shutdown) - run = 0; - - /* - * Use to stop processing units. Should be used when a unit is - * added or removed. - */ - if (run_pause) { - run_hold = TRUE; - syslog(LOG_NOTICE, "run_pause: entering hold state"); - for (;;) { - mDelay(100); - if (! run_pause) - break; - } - syslog(LOG_NOTICE, "run_pause: leaving hold state"); - run_hold = FALSE; - /* - * In case the LCD buffers were cleared, setup the first page. - */ - pthread_mutex_lock(&mutexes[LOCK_LCD]); - lcd_buf_write(1, (char *)" ThermFerm "); - lcd_buf_write(2, (char *)"Version %s ", VERSION); - pthread_mutex_unlock(&mutexes[LOCK_LCD]); - } - - now = time(NULL); - if (now != last) { - /* - * Each second - */ - last = now; - seconds++; - - row = 3; - tm = localtime(&now); - pthread_mutex_lock(&mutexes[LOCK_LCD]); - lcd_buf_write(row++, " %02d-%02d-%04d ", tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900); - lcd_buf_write(row++, " %02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec); - pthread_mutex_unlock(&mutexes[LOCK_LCD]); - - pthread_mutex_lock(&mutexes[LOCK_LCD]); - lcd_buf_write(row, "Room temp N/A "); - pthread_mutex_unlock(&mutexes[LOCK_LCD]); - int updateHT = 0; - if (Config.temp_address) { - rc = device_in(Config.temp_address, &temp); - if (rc == DEVPRESENT_YES) { - if (Config.temp_value != temp) - updateHT = 1; - Config.temp_value = temp; - Config.temp_state = 0; - pthread_mutex_lock(&mutexes[LOCK_LCD]); - lcd_buf_write(row, "Room temp %.1f%c ", Config.temp_value / 1000.0, 0x01); - pthread_mutex_unlock(&mutexes[LOCK_LCD]); - } else if (rc == DEVPRESENT_ERROR) { - Config.temp_state = 1; - } else { - Config.temp_state = 2; - } - mDelay(10); - } - row++; - - pthread_mutex_lock(&mutexes[LOCK_LCD]); - lcd_buf_write(row, " Humidity N/A "); - pthread_mutex_unlock(&mutexes[LOCK_LCD]); - - if (Config.hum_address) { - rc = device_in(Config.hum_address, &temp); - if (rc == DEVPRESENT_YES) { - if (Config.hum_value != temp) - updateHT = 1; - Config.hum_value = temp; - Config.hum_state = 0; - pthread_mutex_lock(&mutexes[LOCK_LCD]); - lcd_buf_write(row, " Humidity %.1f%% ", Config.hum_value / 1000.0); - pthread_mutex_unlock(&mutexes[LOCK_LCD]); - } else if (rc == DEVPRESENT_ERROR) { - Config.hum_state = 1; - } else { - Config.hum_state = 2; - } - mDelay(10); - } - row++; - /* - * If TH(B) changed. or if 5 minutes without - * update, send the NDATA message. - */ - if (updateHT || (now > (ndata + 300))) { - publishNData(false, 0); - ndata = now; - } - - LCDunit = 0; - for (unit = Config.units; unit; unit = unit->next) { - LCDunit++; - do_unit(unit, LCDunit, &seconds, &minutes); - - } /* for units */ - - pthread_mutex_lock(&mutexes[LOCK_MENU]); - if (setupmenu == MENU_NONE) { - pthread_mutex_lock(&mutexes[LOCK_LCD]); - lcd_buf_show(); - pthread_mutex_unlock(&mutexes[LOCK_LCD]); - } - pthread_mutex_unlock(&mutexes[LOCK_MENU]); - - if (seconds == 60) { - seconds = 0; - - /* - * Publish data every minute if unit is active. - */ - for (unit = Config.units; unit; unit = unit->next) { - if (unit->mode != UNITMODE_OFF) { - publishDLog(unit); - if (unit->event_msg) - free(unit->event_msg); - unit->event_msg = NULL; - } - } - - minutes++; - if (minutes == 60) { - minutes = 0; - /* - * Log usage counters every hour - */ - for (unit = Config.units; unit; unit = unit->next) { - syslog(LOG_NOTICE, "Unit `%s' usage heater=%d cooler=%d fan=%d", unit->alias, unit->heater_usage, unit->cooler_usage, unit->fan_usage); - } - } - - /* - * Save the configuration each half hour. - */ - if ((minutes == 15) || (minutes == 45)) - wrconfig(); - } - } - - slcdDummy(slcdHandle); - key = keycheck(); - if (key != KEY_NONE) - panel_key_events(key); - - mDelay(100); - - } while (run); + /* + * Run state table + */ + thermferm(); /* * Stop units processing in a neat way