--- a/thermferm/server.c Sun Apr 28 15:50:42 2024 +0200 +++ b/thermferm/server.c Tue Apr 30 17:26:41 2024 +0200 @@ -26,6 +26,7 @@ #include "one-wire.h" #include "devices.h" #include "server.h" +#include "simulator.h" #include "lcd-buffer.h" #include "xutil.h" #include "mqtt.h" @@ -1003,7 +1004,7 @@ { char *opt, *param, *kwd, *val, ibuf[SS_BUFSIZE]; simulator_list *simulator, *tmps; - int rc, rlen, ival; + int rc, rlen, ival, i; float fval; uuid_t uu; @@ -1024,6 +1025,7 @@ 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 *)"SIMULATOR JSON Get json records"); srv_send(s, (char *)"."); return 0; } @@ -1031,23 +1033,57 @@ if (strcmp(opt, (char *)"LIST") == 0) { srv_send(s, (char *)"212 Simulators list follows:"); for (simulator = Config.simulators; simulator; simulator = simulator->next) { - srv_send(s, (char *)"%s,%s", simulator->uuid, simulator->name); + srv_send(s, (char *)"%s,%d,%s", simulator->uuid, simulator->simno, simulator->name); } srv_send(s, (char *)"."); return 0; } + if (strcmp(opt, (char *)"JSON") == 0) { + char *payload = NULL, *payloadu = NULL; + bool comma = false; + + if (param == NULL) { + srv_send(s, (char *)"212 Simulators json list follows:"); + payload = xstrcpy((char *)"["); + for (simulator = Config.simulators; simulator; simulator = simulator->next) { + if (comma) + payload = xstrcat(payload, (char *)","); + payloadu = simulator_json(simulator); + payload = xstrcat(payload, payloadu); + comma = true; + free(payloadu); + payloadu = NULL; + } + payload = xstrcat(payload, (char *)"]"); + large_send(s, payload); + srv_send(s, (char *)"."); + free(payload); + payload = NULL; + return 0; + } + } + if (param == NULL) { srv_send(s, (char *)"502 Parameter missing"); return 0; } if (strcmp(opt, (char *)"ADD") == 0) { + int highno = 0, count = 0; + char abuf[64]; /* * For now, only one simulator is allowed. */ if (Config.simulators) { + for (tmps = Config.simulators; tmps; tmps = tmps->next) { + if (tmps->simno > highno) + highno = tmps->simno; + count++; + } + } + if (count >= 5) { srv_send(s, (char *)"441 Maximum simulators reached"); return 0; } @@ -1058,10 +1094,33 @@ uuid_generate(uu); uuid_unparse(uu, simulator->uuid); simulator->name = xstrcpy(param); + simulator->simno = highno + 1; + sprintf(abuf, "%d-", simulator->simno); simulator->volume_air = 150; simulator->volume_beer = 50; - simulator->room_temperature = simulator->air_temperature = simulator->beer_temperature = simulator->s_cool_temp = simulator->s_heat_temp = 20.0; + simulator->room_tempaddress = xstrcpy(abuf); + simulator->room_tempaddress = xstrcat(simulator->room_tempaddress, (char *)"SimRoomTemp"); + simulator->room_temperature = simulator->air_temperature = simulator->beer_temperature = simulator->beer_temperature2 = 20.0; + simulator->s_cool_temp = simulator->s_heat_temp = 20.0; + simulator->room_humaddress = xstrcpy(abuf); + simulator->room_humaddress = xstrcat(simulator->room_humaddress, (char *)"SimRoomHum"); simulator->room_humidity = 48.6; + simulator->air_address = xstrcpy(abuf); + simulator->air_address = xstrcat(simulator->air_address, (char *)"SimAirTemp"); + simulator->beer_address = xstrcpy(abuf); + simulator->beer_address = xstrcat(simulator->beer_address, (char *)"SimBeerTemp"); + simulator->beer_address2 = xstrcpy(abuf); + simulator->beer_address2 = xstrcat(simulator->beer_address2, (char *)"SimBeerTemp2"); + simulator->chiller_address = xstrcpy(abuf); + simulator->chiller_address = xstrcat(simulator->chiller_address, (char *)"SimChillerTemp"); + simulator->heater_address = xstrcpy(abuf); + simulator->heater_address = xstrcat(simulator->heater_address, (char *)"SimHeater"); + simulator->cooler_address = xstrcpy(abuf); + simulator->cooler_address = xstrcat(simulator->cooler_address, (char *)"SimCooler"); + simulator->fan_address = xstrcpy(abuf); + simulator->fan_address = xstrcat(simulator->fan_address, (char *)"SimFan"); + simulator->light_address = xstrcpy(abuf); + simulator->light_address = xstrcat(simulator->light_address, (char *)"SimLight"); simulator->chiller_temperature = 1.5; /* Chiller temperature */ simulator->cooler_temp = 1.5; /* Cooling temperature */ simulator->cooler_time = 720; /* About 12 minutes for the cooler plate */ @@ -1069,8 +1128,10 @@ simulator->heater_temp = 150.0; /* Heating temperature */ simulator->heater_time = 3; /* 3 seconds to heat-up */ simulator->heater_size = 0.01; /* 0.01 square meter heater plate */ - simulator->heater_state = simulator->cooler_state = 0; + simulator->air_present = simulator->beer_present = DEVPRESENT_YES; + simulator->beer_present2 = simulator->chiller_present = simulator->cooler_present = simulator->heater_present = DEVPRESENT_UNDEF; simulator->frigo_isolation = 0.002; + simulator->timestamp = time(NULL); simulator->s_yeast_heat = 0.0; simulator->s_yeast_started = simulator->s_cool_changed = simulator->s_heat_changed = (int)0; @@ -1085,12 +1146,14 @@ } } - syslog(LOG_NOTICE, "Simulator %s added", simulator->uuid); + syslog(LOG_NOTICE, "Simulator %s no %d added", simulator->uuid, simulator->simno); srv_send(s, (char *)"211 Simulator %s added", simulator->uuid); return 1; } if (strcmp(opt, (char *)"DEL") == 0) { + // TODO: check devices in use. + // TODO: delete simulated devices. rc = delete_Simulator(param); if (rc) { syslog(LOG_NOTICE, "Simulator %s deleted", param); @@ -1107,22 +1170,45 @@ if (strcmp(simulator->uuid, param) == 0) { srv_send(s, (char *)"213 Simulator record follows:"); srv_send(s, (char *)"NAME,%s", simulator->name); + srv_send(s, (char *)"SIMNO,%d", simulator->simno); 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_TEMPADDRESS,%s", simulator->room_tempaddress); srv_send(s, (char *)"ROOM_TEMPERATURE,%.1f", simulator->room_temperature); + srv_send(s, (char *)"ROOM_HUMADDRESS,%s", simulator->room_humaddress); srv_send(s, (char *)"ROOM_HUMIDITY,%.1f", simulator->room_humidity); + srv_send(s, (char *)"AIR_ADDRESS,%s", simulator->air_address); srv_send(s, (char *)"AIR_TEMPERATURE,%.3f", simulator->air_temperature); + srv_send(s, (char *)"AIR_PRESENT,%s", DEVPRESENT[simulator->air_present]); + srv_send(s, (char *)"BEER_ADDRESS,%s", simulator->beer_address); srv_send(s, (char *)"BEER_TEMPERATURE,%.3f", simulator->beer_temperature); + srv_send(s, (char *)"BEER_PRESENT,%s", DEVPRESENT[simulator->beer_present]); + srv_send(s, (char *)"BEER_ADDRESS2,%s", simulator->beer_address2); + srv_send(s, (char *)"BEER_TEMPERATURE2,%.3f", simulator->beer_temperature2); + srv_send(s, (char *)"BEER_PRESENT2,%s", DEVPRESENT[simulator->beer_present2]); + srv_send(s, (char *)"CHILLER_ADDRESS,%s", simulator->chiller_address); srv_send(s, (char *)"CHILLER_TEMPERATURE,%.3f", simulator->chiller_temperature); + srv_send(s, (char *)"CHILLER_PRESENT,%s", DEVPRESENT[simulator->chiller_present]); + srv_send(s, (char *)"COOLER_ADDRESS,%s", simulator->cooler_address); 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 *)"COOLER_PRESENT,%s", DEVPRESENT[simulator->cooler_present]); + srv_send(s, (char *)"COOLER_POWER,%d", simulator->cooler_power); + srv_send(s, (char *)"HEATER_ADDRESS,%s", simulator->heater_address); 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 *)"HEATER_PRESENT,%s", DEVPRESENT[simulator->heater_present]); + srv_send(s, (char *)"HEATER_POWER,%d", simulator->heater_power); + srv_send(s, (char *)"FAN_ADDRESS,%s", simulator->fan_address); + srv_send(s, (char *)"FAN_PRESENT,%s", DEVPRESENT[simulator->fan_present]); + srv_send(s, (char *)"FAN_POWER,%d", simulator->fan_power); + srv_send(s, (char *)"LIGHT_ADDRESS,%s", simulator->light_address); + srv_send(s, (char *)"LIGHT_PRESENT,%s", DEVPRESENT[simulator->light_present]); + srv_send(s, (char *)"LIGHT_POWER,%d", simulator->light_power); srv_send(s, (char *)"FRIGO_ISOLATION,%.3f", simulator->frigo_isolation); + srv_send(s, (char *)"TIMESTAMP,%ld", (long)simulator->timestamp); srv_send(s, (char *)"."); return 0; } @@ -1142,6 +1228,7 @@ if (strlen(ibuf)) { if (strcmp(ibuf, (char *)".") == 0) { srv_send(s, (char *)"219 Accepted Simulator record"); + simulator->timestamp = time(NULL); return 1; } kwd = strtok(ibuf, ",\0"); @@ -1191,6 +1278,16 @@ simulator->air_temperature = fval; } + } else if (strcmp(kwd, (char *)"AIR_PRESENT") == 0) { + for (i = 0; i < 4; i++) { + if (strcmp(val, DEVPRESENT[i]) == 0) { + if (simulator->air_present != i) + syslog(LOG_NOTICE, "Simulator %s air_present %s to %s", simulator->uuid, DEVPRESENT[simulator->air_present], DEVPRESENT[i]); + simulator->air_present = i; + break; + } + } + } else if (strcmp(kwd, (char *)"BEER_TEMPERATURE") == 0) { if (sscanf(val, "%f", &fval) == 1) { if (simulator->beer_temperature != fval) @@ -1198,6 +1295,33 @@ simulator->beer_temperature = fval; } + } else if (strcmp(kwd, (char *)"BEER_PRESENT") == 0) { + for (i = 0; i < 4; i++) { + if (strcmp(val, DEVPRESENT[i]) == 0) { + if (simulator->beer_present != i) + syslog(LOG_NOTICE, "Simulator %s beer_present %s to %s", simulator->uuid, DEVPRESENT[simulator->beer_present], DEVPRESENT[i]); + simulator->beer_present = i; + break; + } + } + + } else if (strcmp(kwd, (char *)"BEER_TEMPERATURE2") == 0) { + if (sscanf(val, "%f", &fval) == 1) { + if (simulator->beer_temperature2 != fval) + syslog(LOG_NOTICE, "Simulator %s beer temperature2 %.1f to %.1f", simulator->uuid, simulator->beer_temperature2, fval); + simulator->beer_temperature2 = fval; + } + + } else if (strcmp(kwd, (char *)"BEER_PRESENT2") == 0) { + for (i = 0; i < 4; i++) { + if (strcmp(val, DEVPRESENT[i]) == 0) { + if (simulator->beer_present2 != i) + syslog(LOG_NOTICE, "Simulator %s beer_present2 %s to %s", simulator->uuid, DEVPRESENT[simulator->beer_present2], DEVPRESENT[i]); + simulator->beer_present2 = i; + break; + } + } + } else if (strcmp(kwd, (char *)"CHILLER_TEMPERATURE") == 0) { if (sscanf(val, "%f", &fval) == 1) { if (simulator->chiller_temperature != fval) @@ -1205,6 +1329,16 @@ simulator->chiller_temperature = fval; } + } else if (strcmp(kwd, (char *)"CHILLER_PRESENT") == 0) { + for (i = 0; i < 4; i++) { + if (strcmp(val, DEVPRESENT[i]) == 0) { + if (simulator->chiller_present != i) + syslog(LOG_NOTICE, "Simulator %s chiller_present %s to %s", simulator->uuid, DEVPRESENT[simulator->chiller_present], DEVPRESENT[i]); + simulator->chiller_present = i; + break; + } + } + } else if (strcmp(kwd, (char *)"COOLER_TEMP") == 0) { if (sscanf(val, "%f", &fval) == 1) { if (simulator->cooler_temp != fval) @@ -1226,6 +1360,23 @@ simulator->cooler_size = fval; } + } else if (strcmp(kwd, (char *)"COOLER_PRESENT") == 0) { + for (i = 0; i < 4; i++) { + if (strcmp(val, DEVPRESENT[i]) == 0) { + if (simulator->cooler_present != i) + syslog(LOG_NOTICE, "Simulator %s cooler_present %s to %s", simulator->uuid, DEVPRESENT[simulator->cooler_present], DEVPRESENT[i]); + simulator->cooler_present = i; + break; + } + } + + } else if (strcmp(kwd, (char *)"COOLER_POWER") == 0) { + if (sscanf(val, "%d", &ival) == 1) { + if (simulator->cooler_power != ival) + syslog(LOG_NOTICE, "Simulator %s cooler power %d to %d", simulator->uuid, simulator->cooler_power, ival); + simulator->cooler_power = ival; + } + } else if (strcmp(kwd, (char *)"HEATER_TEMP") == 0) { if (sscanf(val, "%f", &fval) == 1) { if (simulator->heater_temp != fval) @@ -1247,19 +1398,56 @@ simulator->heater_size = fval; } - } else if (strcmp(kwd, (char *)"HEATER_STATE") == 0) { - if (sscanf(val, "%d", &ival) == 1) { - if (simulator->heater_state != ival) - syslog(LOG_NOTICE, "Simulator %s heater state %d to %d", simulator->uuid, simulator->heater_state, ival); - simulator->heater_state = ival; - } + } else if (strcmp(kwd, (char *)"HEATER_PRESENT") == 0) { + for (i = 0; i < 4; i++) { + if (strcmp(val, DEVPRESENT[i]) == 0) { + if (simulator->heater_present != i) + syslog(LOG_NOTICE, "Simulator %s heater_present %s to %s", simulator->uuid, DEVPRESENT[simulator->heater_present], DEVPRESENT[i]); + simulator->heater_present = i; + break; + } + } + + } else if (strcmp(kwd, (char *)"HEATER_POWER") == 0) { + if (sscanf(val, "%d", &ival) == 1) { + if (simulator->heater_power != ival) + syslog(LOG_NOTICE, "Simulator %s heater power %d to %d", simulator->uuid, simulator->heater_power, ival); + simulator->heater_power = ival; + } - } else if (strcmp(kwd, (char *)"COOLER_STATE") == 0) { - if (sscanf(val, "%d", &ival) == 1) { - if (simulator->cooler_state != ival) - syslog(LOG_NOTICE, "Simulator %s cooler state %d to %d", simulator->uuid, simulator->cooler_state, ival); - simulator->cooler_state = ival; - } + } else if (strcmp(kwd, (char *)"FAN_PRESENT") == 0) { + for (i = 0; i < 4; i++) { + if (strcmp(val, DEVPRESENT[i]) == 0) { + if (simulator->fan_present != i) + syslog(LOG_NOTICE, "Simulator %s fan_present %s to %s", simulator->uuid, DEVPRESENT[simulator->fan_present], DEVPRESENT[i]); + simulator->fan_present = i; + break; + } + } + + } else if (strcmp(kwd, (char *)"FAN_POWER") == 0) { + if (sscanf(val, "%d", &ival) == 1) { + if (simulator->fan_power != ival) + syslog(LOG_NOTICE, "Simulator %s fan power %d to %d", simulator->uuid, simulator->fan_power, ival); + simulator->fan_power = ival; + } + + } else if (strcmp(kwd, (char *)"LIGHT_PRESENT") == 0) { + for (i = 0; i < 4; i++) { + if (strcmp(val, DEVPRESENT[i]) == 0) { + if (simulator->light_present != i) + syslog(LOG_NOTICE, "Simulator %s light_present %s to %s", simulator->uuid, DEVPRESENT[simulator->light_present], DEVPRESENT[i]); + simulator->light_present = i; + break; + } + } + + } else if (strcmp(kwd, (char *)"LIGHT_POWER") == 0) { + if (sscanf(val, "%d", &ival) == 1) { + if (simulator->fan_power != ival) + syslog(LOG_NOTICE, "Simulator %s light power %d to %d", simulator->uuid, simulator->light_power, ival); + simulator->light_power = ival; + } } else if (strcmp(kwd, (char *)"FRIGO_ISOLATION") == 0) { if (sscanf(val, "%f", &fval) == 1) {