thermferm/thermferm.c

changeset 397
00ca08f5a6f8
parent 395
e32e83550963
child 398
efdfef1677d1
equal deleted inserted replaced
396:66d4e137b99d 397:00ca08f5a6f8
809 809
810 810
811 811
812 int server(void) 812 int server(void)
813 { 813 {
814 char buf[1024], *filename, target[40], heater[40], cooler[40], fan[40], door[40]; 814 char buf[1024], *filename, target_lo[40], target_hi[40], heater[40], cooler[40], fan[40], door[40];
815 char use_heater[40], use_cooler[40], use_fan[40], room_temp[40]; 815 char use_heater[40], use_cooler[40], use_fan[40], room_temp[40];
816 time_t now, last = (time_t)0; 816 time_t now, last = (time_t)0;
817 units_list *unit; 817 units_list *unit;
818 profiles_list *profile; 818 profiles_list *profile;
819 prof_step *step; 819 prof_step *step;
824 int row, key; 824 int row, key;
825 #else 825 #else
826 long t = 0; 826 long t = 0;
827 #endif 827 #endif
828 int current_step, valid_step, time_until_now; 828 int current_step, valid_step, time_until_now;
829 float previous_target; 829 float previous_target_lo, previous_target_hi;
830 830
831 831
832 if (lockprog((char *)"thermferm")) { 832 if (lockprog((char *)"thermferm")) {
833 syslog(LOG_NOTICE, "Can't lock"); 833 syslog(LOG_NOTICE, "Can't lock");
834 return 1; 834 return 1;
1142 for (profile = Config.profiles; profile; profile = profile->next) { 1142 for (profile = Config.profiles; profile; profile = profile->next) {
1143 if (strcmp(unit->profile, profile->uuid) == 0) { 1143 if (strcmp(unit->profile, profile->uuid) == 0) {
1144 1144
1145 switch (unit->prof_state) { 1145 switch (unit->prof_state) {
1146 case PROFILE_OFF: 1146 case PROFILE_OFF:
1147 unit->prof_target = profile->inittemp; 1147 unit->prof_target_lo = profile->inittemp_lo;
1148 unit->prof_target_hi = profile->inittemp_hi;
1149 unit->prof_fridge_mode = 0;
1148 unit->prof_percent = 0; 1150 unit->prof_percent = 0;
1149 break; 1151 break;
1150 case PROFILE_PAUSE: 1152 case PROFILE_PAUSE:
1151 /* 1153 /*
1152 * Keep current temperature, measure pause time. For 1154 * Keep current temperature, measure pause time. For
1156 case PROFILE_RUN: 1158 case PROFILE_RUN:
1157 /* 1159 /*
1158 * Calculate current profile step and desired temperature. 1160 * Calculate current profile step and desired temperature.
1159 * When all steps are done, set state to PROFILE_DONE. 1161 * When all steps are done, set state to PROFILE_DONE.
1160 */ 1162 */
1161 previous_target = profile->inittemp; 1163 previous_target_lo = profile->inittemp_lo;
1164 previous_target_hi = profile->inittemp_hi;
1162 time_until_now = current_step = 0; 1165 time_until_now = current_step = 0;
1163 run_seconds = (int)(now - unit->prof_started - unit->prof_paused); 1166 run_seconds = (int)(now - unit->prof_started - unit->prof_paused);
1164 run_minutes = run_seconds / 60; 1167 run_minutes = run_seconds / 60;
1165 run_hours = run_minutes / 60; 1168 run_hours = run_minutes / 60;
1166 if (debug) 1169 if (debug)
1214 if ((run_hours >= time_until_now) && (run_hours < (time_until_now + step->steptime + step->resttime))) { 1217 if ((run_hours >= time_until_now) && (run_hours < (time_until_now + step->steptime + step->resttime))) {
1215 /* 1218 /*
1216 * This is our current step 1219 * This is our current step
1217 */ 1220 */
1218 valid_step = TRUE; 1221 valid_step = TRUE;
1222 unit->prof_fridge_mode = step->fridge_mode;
1219 if (debug) 1223 if (debug)
1220 fprintf(stdout, "step=%d step_pos=%d step=%d/%d target=%.1f ", 1224 fprintf(stdout, "step=%d step_pos=%d step=%d/%d target=%.1f..%.1f ",
1221 current_step, run_hours - time_until_now, 1225 current_step, run_hours - time_until_now,
1222 step->steptime, step->resttime, step->target); 1226 step->steptime, step->resttime, step->target_lo, step->target_hi);
1223 if ((run_hours - time_until_now) < step->steptime) { 1227 if ((run_hours - time_until_now) < step->steptime) {
1224 unit->prof_target = previous_target + (((run_minutes - (time_until_now * 60.0)) / (step->steptime * 60.0)) * (step->target - previous_target)); 1228 unit->prof_target_lo = previous_target_lo + (((run_minutes - (time_until_now * 60.0)) / (step->steptime * 60.0)) * (step->target_lo - previous_target_lo));
1229 unit->prof_target_hi = previous_target_hi + (((run_minutes - (time_until_now * 60.0)) / (step->steptime * 60.0)) * (step->target_hi - previous_target_hi));
1225 if (debug) 1230 if (debug)
1226 fprintf(stdout, "tempshift=%.1f minutes=%d duration=%d temp_move=%.3f ", 1231 fprintf(stdout, "tempshift=%.1f..%.1f minutes=%d duration=%d temp_move=%.3f..%.3f ",
1227 step->target - previous_target, run_minutes - (time_until_now * 60), 1232 step->target_lo - previous_target_lo,
1228 step->steptime * 60, unit->prof_target); 1233 step->target_hi - previous_target_hi,
1234 run_minutes - (time_until_now * 60),
1235 step->steptime * 60, unit->prof_target_lo, unit->prof_target_hi);
1229 } else { 1236 } else {
1230 unit->prof_target = step->target; 1237 unit->prof_target_lo = step->target_lo;
1231 fprintf(stdout, "resting target=%.1f ", step->target); 1238 unit->prof_target_hi = step->target_hi;
1239 if (debug)
1240 fprintf(stdout, "resting target=%.1f..%.1f ", step->target_lo, step->target_hi);
1232 } 1241 }
1233 break; 1242 break;
1234 } 1243 }
1235 time_until_now += step->steptime + step->resttime; 1244 time_until_now += step->steptime + step->resttime;
1236 previous_target = step->target; 1245 previous_target_lo = step->target_lo;
1246 previous_target_hi = step->target_hi;
1237 } 1247 }
1238 if (debug) 1248 if (debug)
1239 fprintf(stdout, " %s %02d:%02d\n", valid_step ? "TRUE":"FALSE", minutes, seconds); 1249 fprintf(stdout, " %s %02d:%02d\n", valid_step ? "TRUE":"FALSE", minutes, seconds);
1240 1250
1241 if (valid_step == TRUE) { 1251 if (valid_step == TRUE) {
1242 unit->prof_percent = (100 * run_minutes) / tot_minutes; 1252 unit->prof_percent = (100 * run_minutes) / tot_minutes;
1243 if (((minutes == 10) || (minutes == 40)) && (seconds == 1)) { 1253 if (((minutes == 10) || (minutes == 40)) && (seconds == 1)) {
1244 syslog(LOG_NOTICE, "Profile `%s' running %dd %02d:%02d in step %d, %d%% done, target %.3f degrees", 1254 syslog(LOG_NOTICE, "Profile `%s' running %dd %02d:%02d in step %d, %d%% done, target %s %.3f..%.3f degrees",
1245 profile->name, run_hours / 24, run_hours % 24, run_minutes % 60, current_step, 1255 profile->name, run_hours / 24, run_hours % 24, run_minutes % 60, current_step,
1246 unit->prof_percent, unit->prof_target); 1256 unit->prof_percent, unit->prof_fridge_mode ? (char *)"air":(char *)"beer",
1257 unit->prof_target_lo, unit->prof_target_hi);
1247 } 1258 }
1248 } else { 1259 } else {
1249 /* 1260 /*
1250 * No more steps to do 1261 * No more steps to do
1251 */ 1262 */
1257 1268
1258 case PROFILE_DONE: 1269 case PROFILE_DONE:
1259 /* 1270 /*
1260 * Keep this state, set target temperature to the last step. 1271 * Keep this state, set target temperature to the last step.
1261 */ 1272 */
1262 previous_target = profile->inittemp; 1273 previous_target_lo = profile->inittemp_lo;
1274 previous_target_hi = profile->inittemp_hi;
1275 unit->prof_fridge_mode = profile->fridge_mode;
1263 for (step = profile->steps; step; step = step->next) { 1276 for (step = profile->steps; step; step = step->next) {
1264 if (step->steptime == 0) 1277 if (step->steptime == 0)
1265 break; 1278 break;
1266 previous_target = step->target; 1279 previous_target_lo = step->target_lo;
1280 previous_target_hi = step->target_hi;
1281 unit->prof_fridge_mode = step->fridge_mode;
1282
1267 } 1283 }
1268 unit->prof_target = previous_target; 1284 unit->prof_target_lo = previous_target_lo;
1285 unit->prof_target_hi = previous_target_hi;
1286 unit->prof_fridge_mode = step->fridge_mode;
1269 unit->prof_percent = 100; 1287 unit->prof_percent = 100;
1270 break; 1288 break;
1271 } /* switch */ 1289 } /* switch */
1272 } 1290 }
1273 } 1291 }
1367 } else if (unit->mode == UNITMODE_BEER) { 1385 } else if (unit->mode == UNITMODE_BEER) {
1368 unit->PID_cool->SetP = unit->PID_heat->SetP = unit->beer_set; 1386 unit->PID_cool->SetP = unit->PID_heat->SetP = unit->beer_set;
1369 unit->PID_cool->Input = unit->PID_heat->Input = unit->beer_temperature / 1000.0; 1387 unit->PID_cool->Input = unit->PID_heat->Input = unit->beer_temperature / 1000.0;
1370 unit->PID_cool->Mode = unit->PID_heat->Mode = PID_MODE_AUTO; 1388 unit->PID_cool->Mode = unit->PID_heat->Mode = PID_MODE_AUTO;
1371 } else if (unit->mode == UNITMODE_PROFILE) { 1389 } else if (unit->mode == UNITMODE_PROFILE) {
1372 unit->PID_cool->SetP = unit->PID_heat->SetP = unit->prof_target; 1390 unit->PID_cool->SetP = unit->prof_target_hi;
1373 unit->PID_cool->Input = unit->PID_heat->Input = unit->beer_temperature / 1000.0; 1391 unit->PID_heat->SetP = unit->prof_target_lo;
1392 if (unit->prof_fridge_mode)
1393 unit->PID_cool->Input = unit->PID_heat->Input = unit->air_temperature / 1000.0;
1394 else
1395 unit->PID_cool->Input = unit->PID_heat->Input = unit->beer_temperature / 1000.0;
1374 unit->PID_cool->Mode = unit->PID_heat->Mode = PID_MODE_AUTO; 1396 unit->PID_cool->Mode = unit->PID_heat->Mode = PID_MODE_AUTO;
1375 } 1397 }
1376 1398
1377 /* 1399 /*
1378 * PID controller compute 1400 * PID controller compute
1515 * Log temperature and status every minute if unit is active. 1537 * Log temperature and status every minute if unit is active.
1516 */ 1538 */
1517 for (unit = Config.units; unit; unit = unit->next) { 1539 for (unit = Config.units; unit; unit = unit->next) {
1518 if (unit->mode != UNITMODE_OFF) { 1540 if (unit->mode != UNITMODE_OFF) {
1519 1541
1520 snprintf(target, 39, "NA"); 1542 snprintf(target_lo, 39, "NA");
1543 snprintf(target_hi, 39, "NA");
1521 snprintf(heater, 39, "NA"); 1544 snprintf(heater, 39, "NA");
1522 snprintf(cooler, 39, "NA"); 1545 snprintf(cooler, 39, "NA");
1523 snprintf(fan, 39, "NA"); 1546 snprintf(fan, 39, "NA");
1524 snprintf(door, 39, "NA"); 1547 snprintf(door, 39, "NA");
1525 snprintf(use_heater, 39, "NA"); 1548 snprintf(use_heater, 39, "NA");
1526 snprintf(use_cooler, 39, "NA"); 1549 snprintf(use_cooler, 39, "NA");
1527 snprintf(use_fan, 39, "NA"); 1550 snprintf(use_fan, 39, "NA");
1528 snprintf(room_temp, 39, "NA"); 1551 snprintf(room_temp, 39, "NA");
1529 1552
1530 if (unit->mode == UNITMODE_BEER) 1553 if (unit->mode == UNITMODE_BEER) {
1531 snprintf(target, 39, "%.1f", unit->beer_set); 1554 snprintf(target_lo, 39, "%.1f", unit->beer_set);
1532 else if (unit->mode == UNITMODE_FRIDGE) 1555 snprintf(target_hi, 39, "%.1f", unit->beer_set);
1533 snprintf(target, 39, "%.1f", unit->fridge_set); 1556 } else if (unit->mode == UNITMODE_FRIDGE) {
1534 else if (unit->mode == UNITMODE_PROFILE) 1557 snprintf(target_lo, 39, "%.1f", unit->fridge_set);
1535 snprintf(target, 39, "%.1f", unit->prof_target); 1558 snprintf(target_hi, 39, "%.1f", unit->fridge_set);
1559 } else if (unit->mode == UNITMODE_PROFILE) {
1560 snprintf(target_lo, 39, "%.1f", unit->prof_target_lo);
1561 snprintf(target_hi, 39, "%.1f", unit->prof_target_hi);
1562 }
1536 1563
1537 if (unit->heater_address) { 1564 if (unit->heater_address) {
1538 snprintf(heater, 39, "%d", unit->heater_state); 1565 snprintf(heater, 39, "%d", unit->heater_state);
1539 snprintf(use_heater, 39, "%d", unit->heater_usage); 1566 snprintf(use_heater, 39, "%d", unit->heater_usage);
1540 } 1567 }
1551 } 1578 }
1552 if (Config.temp_address) { 1579 if (Config.temp_address) {
1553 snprintf(room_temp, 39, "%.3f", Config.temp_value / 1000.0); 1580 snprintf(room_temp, 39, "%.3f", Config.temp_value / 1000.0);
1554 } 1581 }
1555 1582
1556 snprintf(buf, 1023, "%s,%.3f,%.3f,%s,%s,%s,%s,%s,%s,%s,%s,%s", 1583 snprintf(buf, 1023, "%s,%.3f,%.3f,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s",
1557 UNITMODE[unit->mode], unit->air_temperature / 1000.0, 1584 UNITMODE[unit->mode], unit->air_temperature / 1000.0,
1558 unit->beer_temperature / 1000.0, target, heater, cooler, fan, door, use_heater, use_cooler, use_fan, room_temp); 1585 unit->beer_temperature / 1000.0,
1586 target_lo, heater, cooler, fan, door, use_heater, use_cooler, use_fan, room_temp, target_hi);
1559 filename = xstrcpy(unit->name); 1587 filename = xstrcpy(unit->name);
1560 filename = xstrcat(filename, (char *)".log"); 1588 filename = xstrcat(filename, (char *)".log");
1561 logger(filename, buf); 1589 logger(filename, buf);
1562 free(filename); 1590 free(filename);
1563 filename = NULL; 1591 filename = NULL;

mercurial