Wed, 10 Jun 2020 09:43:51 +0200
SDK settings to reduce bin size. Some log messages to debug level. Added KWH usage registration. Added equipment power usage for HLT and MLT. Equipment database upgraded to version 2, expandable. Fixed some screen errors during temperature mash steps.
/** * @file config.c * @brief BrewBoard configuration files. */ #include "config.h" static const char *TAG = "config"; void write_config() { uint8_t *dst = (uint8_t *)&config; FILE *f = fopen("/spiffs/etc/config.conf", "w+"); if (f == NULL) { ESP_LOGE(TAG, "write /spiffs/etc/config.conf failed"); return; } size_t bytes = fwrite(dst, 1, sizeof(config), f); fclose(f); if (bytes != sizeof(config)) { ESP_LOGE(TAG, "/spiffs/etc/config.conf written %d/%d bytes", bytes, sizeof(config)); } } void read_config() { uint8_t *dst; uint8_t mac_addr[8] = {0}; FILE *f = fopen("/spiffs/etc/config.conf", "r"); if (f == NULL) { // No configuration yet, create it. esp_efuse_mac_get_default(mac_addr); config.Version = 1; config.Unit = 'C'; config.BoilTemperature = 99.0; config.AskAdd = true; config.AskRemove = true; config.AskIodine = true; config.IodineTime = 30; config.EquipmentRec = 1; sprintf(config.hostname, "brewboard-%02x%02x%02x", mac_addr[3], mac_addr[4], mac_addr[5]); sprintf(config.ap_ssid, "brewboardAP-%02x%02x%02x", mac_addr[3], mac_addr[4], mac_addr[5]); sprintf(config.ap_pwd, "%s", "triplehop"); config.ap_channel = 5; config.ap_ssid_hidden = 0; config.ap_bandwidth = WIFI_BW_HT20; config.ts_xleft = 0; config.ts_xright = 3600; config.ts_ytop = 3600; config.ts_ybottom = 0; config.RecipeRec = 1; sprintf(config.uuid, "c0ffeeee-dead-beef-cafe-%02x%02x%02x%02x%02x%02x", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); write_config(); } else { dst = (uint8_t*)&config; fread(dst, 1, sizeof(config), f); fclose(f); } } void append_equipment() { return; uint8_t *dst = (uint8_t *)&equipment; FILE *f = fopen("/spiffs/etc/equipments.conf", "a"); if (f == NULL) { ESP_LOGE(TAG, "append /spiffs/etc/equipments.conf failed"); return; } size_t bytes = fwrite(dst, 1, equipment_hdr.recsize, f); fclose(f); ESP_LOGI(TAG, "/spiffs/etc/equipments.conf appended %d bytes", bytes); } void read_equipment(int RecNo) { size_t bytes; uint8_t *dst; FILE *f = fopen("/spiffs/etc/equipments.conf", "r"); if (f == NULL) { // No configuration yet, create it. dst = (uint8_t*)&equipment_hdr; memset(dst, 0, sizeof(equipment_hdr)); equipment_hdr.version = EQUIPMENT_VERSION; equipment_hdr.hdrsize = sizeof(equipment_hdr); equipment_hdr.recsize = sizeof(equipment); f = fopen("/spiffs/etc/equipments.conf", "w"); bytes = fwrite(dst, 1, sizeof(equipment_hdr), f); if (bytes != sizeof(equipment_hdr)) { ESP_LOGE(TAG, "/spiffs/etc/equipment.conf write header, %d/%d bytes", bytes, sizeof(equipment_hdr)); } dst = (uint8_t*)&equipment; memset(dst, 0, sizeof(equipment)); equipment.MLT_watt = 2000; equipment.HLT_watt = 2000; sprintf(equipment.Name, "default"); equipment.BoilPower = 80; equipment.MashPower = 100; equipment.PumpCycle = 8; equipment.PumpRest = 2; equipment.PumpPreMash = true; equipment.PumpOnMash = true; equipment.PumpMashOut = true; equipment.PumpOnBoil = false; equipment.PumpMaxTemp = 80; equipment.PIDPipe = true; equipment.SSR2 = 0; equipment.TempHLT = 85.0; equipment.PID_kP = 200.0; equipment.PID_kI = 2.0; equipment.PID_kD = 1.5; equipment.SampleTime = 3000; bytes = fwrite(dst, 1, sizeof(equipment), f); fclose(f); } else { /* * Try to read the new header */ dst = (uint8_t*)&equipment_hdr; fseek(f, 0, SEEK_SET); bytes = fread(dst, 1, sizeof(equipment_hdr), f); if (bytes != sizeof(equipment_hdr)) { ESP_LOGE(TAG, "/spiffs/etc/equipments.conf read header, %d/%d bytes", bytes, sizeof(equipment_hdr)); fclose(f); return; } #if 0 if (equipment_hdr.version < EQUIPMENT_VERSION) { FILE *nf = fopen("/spiffs/etc/equipments.new", "w"); ESP_LOGW(TAG, "/spiffs/etc/equipments.conf version %d, new %d", equipment_hdr.version, EQUIPMENT_VERSION); dst = (uint8_t*)&equipment_hdr; memset(dst, 0, sizeof(equipment_hdr)); equipment_hdr.version = EQUIPMENT_VERSION; equipment_hdr.hdrsize = sizeof(equipment_hdr); equipment_hdr.recsize = sizeof(equipment); bytes = fwrite(dst, 1, sizeof(equipment_hdr), nf); fseek(f, 0, SEEK_SET); dst = (uint8_t*)&recipe; while ((bytes = fread(dst, 1, equipment_hdr.recsize, f))) { // Upgrade data here bytes = fwrite(dst, 1, sizeof(equipment), nf); if (bytes != sizeof(equipment)) { ESP_LOGE(TAG, "/spiffs/etc/equipments.new write data, %d/%d bytes", bytes, sizeof(equipment)); } } // Update the header with new sizes fclose(nf); fclose(f); rename("/spiffs/etc/equipments.conf", "/spiffs/etc/equipments.old"); rename("/spiffs/etc/equipments.new", "/spiffs/etc/equipments.conf"); unlink("/spiffs/etc/equipments.old"); f = fopen("/spiffs/etc/equipments.conf", "r"); } #endif dst = (uint8_t*)&equipment; fseek(f, (RecNo - 1) * equipment_hdr.recsize + equipment_hdr.hdrsize, SEEK_SET); bytes = fread(dst, 1, equipment_hdr.recsize, f); fclose(f); if (bytes != equipment_hdr.recsize) { ESP_LOGE(TAG, "/spiffs/etc/equipments.conf read record %d, %d/%d bytes", RecNo, bytes, equipment_hdr.recsize); } else { ESP_LOGD(TAG, "/spiffs/etc/equipments.conf read %d bytes, record %d: %s", bytes, RecNo, equipment.Name); } } } void write_equipment(int RecNo) { uint8_t *dst = (uint8_t *)&equipment; FILE *f; f = fopen("/spiffs/etc/equipments.conf", "r+"); if (f == NULL) { ESP_LOGE(TAG, "write /spiffs/etc/equipments.conf failed"); return; } fseek(f, (RecNo - 1) * equipment_hdr.recsize + equipment_hdr.hdrsize, SEEK_SET); size_t bytes = fwrite(dst, 1, equipment_hdr.recsize, f); fclose(f); if (bytes != equipment_hdr.recsize) ESP_LOGE(TAG, "/spiffs/etc/equipments.conf write record %d, %d/%d bytes", RecNo, bytes, equipment_hdr.recsize); else ESP_LOGI(TAG, "/spiffs/etc/equipments.conf update record %d, %d bytes", RecNo, bytes); } void delete_equipment(int RecNo) { return; int RecRead = 1, RecWrite = 1; FILE *n, *o; uint8_t *dst; size_t bytes; n = fopen("/spiffs/etc/equipments.new", "a"); if (n == NULL) { ESP_LOGE(TAG, "cannot create /spiffs/etc/equipments.new"); return; } o = fopen("/spiffs/etc/equipments.conf", "r"); if (o == NULL) { ESP_LOGE(TAG, "cannot open spiffs/etc/equipments.conf for reading"); fclose(n); return; } dst = (uint8_t*)&equipment_hdr; fread(dst, 1, equipment_hdr.hdrsize, o); fwrite(dst, 1, equipment_hdr.hdrsize, n); dst = (uint8_t*)&equipment; while (true) { bytes = fread(dst, 1, equipment_hdr.recsize, o); if (bytes == 0) break; if (RecRead != RecNo) { // Record to copy if ((config.EquipmentRec == RecRead) && (config.EquipmentRec != RecWrite)) { // We need to change the default record. config.EquipmentRec = RecWrite; write_config(); } fwrite(dst, 1, equipment_hdr.recsize, n); RecWrite++; } RecRead++; } fclose(o); fclose(n); rename("/spiffs/etc/equipments.conf", "/spiffs/etc/equipments.old"); rename("/spiffs/etc/equipments.new", "/spiffs/etc/equipments.conf"); unlink("/spiffs/etc/equipments.old"); ESP_LOGI(TAG, "Deleted equipment %d", RecNo); } int add_station(uint8_t *SSID, uint8_t *Password) { FILE *f; uint8_t *dst = (uint8_t *)&wifiStation; if (read_station(SSID) >= 0) { ESP_LOGE(TAG, "add_station %s already excists", SSID); return -1; } f = fopen("/spiffs/etc/stations.conf", "a+"); if (f == NULL) { ESP_LOGE(TAG, "write /spiffs/etc/stations.conf failed"); return -1; } memset(dst, 0, sizeof(wifiStation)); sprintf(wifiStation.SSID, "%s", (char *)SSID); sprintf(wifiStation.Password, "%s", (char *)Password); wifiStation.hide = false; fwrite(dst, 1, sizeof(wifiStation), f); fclose(f); ESP_LOGI(TAG, "add_station %s record: %d", (char *)SSID, read_station(SSID)); /* Return the record number */ return read_station(SSID); } int read_station(uint8_t *SSID) { uint8_t *dst = (uint8_t *)&wifiStation; static int rc; FILE *f; size_t bytes; if ((SSID == NULL) || (strlen((char *)SSID) == 0)) { ESP_LOGI(TAG, "read_station(NULL)"); return -1; } memset(dst, 0, sizeof(wifiStation)); f = fopen("/spiffs/etc/stations.conf", "r+"); if (f == NULL) { f = fopen("/spiffs/etc/stations.conf", "w+"); fclose(f); ESP_LOGI(TAG, "/spiffs/etc/stations.conf created, return -1"); return -1; } rc = 0; fseek(f, 0, SEEK_SET); while (1) { bytes = fread(dst, 1, sizeof(wifiStation), f); if (bytes < sizeof(wifiStation)) { fclose(f); memset(dst, 0, sizeof(wifiStation)); return -1; } if (strcmp(wifiStation.SSID, (char *)SSID) == 0) { // Fount it fclose(f); return rc; } rc++; } return -1; } void remove_station(uint8_t *SSID) { FILE *n, *o; uint8_t *dst; size_t bytes; n = fopen("/spiffs/etc/stations.new", "a"); if (n == NULL) { ESP_LOGE(TAG, "cannot create /spiffs/etc/stations.new"); return; } o = fopen("/spiffs/etc/stations.conf", "r"); if (o == NULL) { ESP_LOGE(TAG, "cannot open spiffs/etc/stations.conf for reading"); fclose(n); return; } dst = (uint8_t*)&wifiStation; while (true) { bytes = fread(dst, 1, sizeof(wifiStation), o); if (bytes == 0) break; if ((strcmp((char *)SSID, wifiStation.SSID) == 0) || (strlen(wifiStation.SSID) == 0)) { // Record to delete, don't copy } else { fwrite(dst, 1, sizeof(wifiStation), n); } } fclose(o); fclose(n); rename("/spiffs/etc/stations.conf", "/spiffs/etc/stations.old"); rename("/spiffs/etc/stations.new", "/spiffs/etc/stations.conf"); unlink("/spiffs/etc/stations.old"); } int blacklist_station(uint8_t *SSID) { return -1; } void write_runtime() { uint8_t *dst = (uint8_t *)&runtime; FILE *f = fopen("/spiffs/etc/runtime.conf", "w+"); if (f == NULL) { ESP_LOGE(TAG, "write /spiffs/etc/runtime.conf failed"); return; } size_t bytes = fwrite(dst, 1, sizeof(runtime), f); fclose(f); if (bytes != sizeof(runtime)) { ESP_LOGE(TAG, "/spiffs/etc/runtime.conf written %d/%d bytes", bytes, sizeof(runtime)); } } void read_runtime() { uint8_t *dst; FILE *f = fopen("/spiffs/etc/runtime.conf", "r"); if (f == NULL) { // No runtime yet, create it. runtime.Version = 1; runtime.AutoModeStarted = false; runtime.StageResume = 0; runtime.StageTimeLeft = 0; runtime.HopAddition = 0; runtime.ManualMLT = 45.0; runtime.ManualHLT = 45.0; runtime.BrewStart = (time_t)0; runtime.Logfile[0] = '\0'; runtime.PumpCooling = false; runtime.TimeBrewing = 0; runtime.MashStep = 0; runtime.MLT_usage = 0; runtime.HLT_usage = 0; write_runtime(); } else { dst = (uint8_t*)&runtime; size_t bytes = fread(dst, 1, sizeof(runtime), f); fclose(f); if (bytes != sizeof(runtime)) { ESP_LOGE(TAG, "/spiffs/etc/runtime.conf read %d/%d bytes", bytes, sizeof(runtime)); runtime.MLT_usage = 0; runtime.HLT_usage = 0; } #if 0 printf("Auto started %s\n", runtime.AutoModeStarted ? "yes":"no"); printf("Stage resume %d\n", runtime.StageResume); printf("Stage time left %d\n", runtime.StageTimeLeft); printf("Hop addition %d\n", runtime.HopAddition); printf("Brew start %d\n", (int)runtime.BrewStart); printf("Log file %s\n", runtime.Logfile); printf("Pump cooling %s\n", runtime.PumpCooling ? "yes":"no"); printf("Time brewing %d\n", runtime.TimeBrewing); #endif } } void append_recipe() { uint8_t *dst = (uint8_t *)&recipe; FILE *f = fopen("/spiffs/etc/recipe.conf", "a"); if (f == NULL) { ESP_LOGE(TAG, "append /spiffs/etc/recipe.conf failed"); return; } size_t bytes = fwrite(dst, 1, recipe_hdr.recsize, f); fclose(f); ESP_LOGI(TAG, "/spiffs/etc/recipe.conf appended %d bytes", bytes); } void write_recipe(int RecNo) { uint8_t *dst = (uint8_t *)&recipe; FILE *f = fopen("/spiffs/etc/recipe.conf", "r+"); if (f == NULL) { ESP_LOGE(TAG, "write /spiffs/etc/recipe.conf failed"); return; } fseek(f, (RecNo - 1) * recipe_hdr.recsize + recipe_hdr.hdrsize, SEEK_SET); size_t bytes = fwrite(dst, 1, recipe_hdr.recsize, f); fclose(f); if (bytes != recipe_hdr.recsize) { ESP_LOGE(TAG, "/spiffs/etc/recipe.conf write record %d, %d/%d bytes", RecNo, bytes, recipe_hdr.recsize); } } void read_recipe(int RecNo) { uint8_t *dst; size_t bytes; FILE *f = fopen("/spiffs/etc/recipe.conf", "r"); if (f == NULL) { // No recipe yet, create it. dst = (uint8_t*)&recipe_hdr; memset(dst, 0, sizeof(recipe_hdr)); recipe_hdr.version = RECIPE_VERSION; recipe_hdr.hdrsize = sizeof(recipe_hdr); recipe_hdr.recsize = sizeof(recipe); recipe_hdr.mashmax = MASH_MAX; recipe_hdr.additionmax = ADDITION_MAX; f = fopen("/spiffs/etc/recipe.conf", "w"); bytes = fwrite(dst, 1, sizeof(recipe_hdr), f); if (bytes != sizeof(recipe_hdr)) { ESP_LOGE(TAG, "/spiffs/etc/recipe.conf write header, %d/%d bytes", bytes, sizeof(recipe_hdr)); } dst = (uint8_t*)&recipe; memset(dst, 0, sizeof(recipe)); sprintf(recipe.Name, "Recipe 1"); sprintf(recipe.Code, "001"); sprintf(recipe.MashStep[0].Name, "Mash-in"); recipe.MashStep[0].Type = MASHTYPE_INFUSION; recipe.MashStep[0].Step_temp = recipe.MashStep[0].End_temp = recipe.MashStep[0].Infuse_temp = 67.5; recipe.MashStep[0].Infuse_amount = 15.0; recipe.MashStep[0].Step_time = 1; recipe.MashStep[0].Ramp_time = 1; for (int i = 1; i < MASH_MAX; i++) recipe.MashStep[i].Type = MASHTYPE_TEMPERATURE; sprintf(recipe.MashStep[1].Name, "Mash"); recipe.MashStep[1].Step_temp = recipe.MashStep[1].End_temp = 67.0; recipe.MashStep[1].Step_time = 75; recipe.MashStep[1].Ramp_time = 1; sprintf(recipe.MashStep[2].Name, "Mash-out"); recipe.MashStep[2].Step_temp = recipe.MashStep[2].End_temp = 78.0; recipe.MashStep[2].Step_time = 5; recipe.MashStep[2].Ramp_time = 11; recipe.Mashsteps = 3; recipe.BoilTime = 60; recipe.Additions = 2; sprintf(recipe.Addition[0].Name, "Hop"); recipe.Addition[0].Time = 60; recipe.Addition[0].Type = ADDITION_HOP; sprintf(recipe.Addition[1].Name, "Hop"); recipe.Addition[1].Time = 10; recipe.Addition[1].Type = ADDITION_HOP; recipe.CoolTemp = 20.0; recipe.Whirlpool9 = 0; recipe.Whirlpool7 = 0; recipe.Whirlpool6 = 0; recipe.Whirlpool2 = 0; recipe.SpargeTemp = 85.0; bytes = fwrite(dst, 1, sizeof(recipe), f); fclose(f); } else { /* * Try to read the new file header */ dst = (uint8_t*)&recipe_hdr; fseek(f, 0, SEEK_SET); bytes = fread(dst, 1, sizeof(recipe_hdr), f); if (bytes != sizeof(recipe_hdr)) { ESP_LOGE(TAG, "/spiffs/etc/recipe.conf read header, %d/%d bytes", bytes, sizeof(recipe_hdr)); fclose(f); return; } /* if (recipe_hdr.version < RECIPE_VERSION) { FILE *nf = fopen("/spiffs/etc/recipe.new", "w"); ESP_LOGI(TAG, "/spiffs/etc/recipe.conf version %d, new %d", recipe_hdr.version, RECIPE_VERSION); fseek(f, recipe_hdr.hdrsize, SEEK_SET); dst = (uint8_t*)&recipe; while ((bytes = fread(dst, 1, recipe_hdr.recsize, f))) { // Upgrade data here bytes = fwrite(dst, 1, sizeof(recipe), nf); if (bytes != sizeof(recipe)) { ESP_LOGE(TAG, "/spiffs/etc/recipe.new write data, %d/%d bytes", bytes, sizeof(recipe)); } } // Update the header with new sizes fclose(nf); fclose(f); rename("/spiffs/etc/recipe.conf", "/spiffs/etc/recipe.old"); rename("/spiffs/etc/recipe.new", "/spiffs/etc/recipe.conf"); unlink("/spiffs/etc/recipe.old"); f = fopen("/spiffs/etc/recipe.conf", "r"); } */ dst = (uint8_t*)&recipe; fseek(f, (RecNo - 1) * recipe_hdr.recsize + recipe_hdr.hdrsize, SEEK_SET); bytes = fread(dst, 1, sizeof(recipe), f); fclose(f); if (bytes != sizeof(recipe)) { ESP_LOGE(TAG, "/spiffs/etc/recipe.conf read record %d, %d/%d bytes", RecNo, bytes, sizeof(recipe)); } } } void delete_recipe(int RecNo) { int RecRead = 1, RecWrite = 1; FILE *n, *o; uint8_t *dst; size_t bytes; n = fopen("/spiffs/etc/recipe.new", "a"); if (n == NULL) { ESP_LOGE(TAG, "cannot create /spiffs/etc/recipe.new"); return; } o = fopen("/spiffs/etc/recipe.conf", "r"); if (o == NULL) { ESP_LOGE(TAG, "cannot open spiffs/etc/recipe.conf for reading"); fclose(n); return; } dst = (uint8_t*)&recipe_hdr; fread(dst, 1, recipe_hdr.hdrsize, o); fwrite(dst, 1, recipe_hdr.hdrsize, n); dst = (uint8_t*)&recipe; while (true) { bytes = fread(dst, 1, recipe_hdr.recsize, o); if (bytes == 0) break; if (RecRead != RecNo) { // Record to copy if ((config.RecipeRec == RecRead) && (config.RecipeRec != RecWrite)) { // We need to change the default record. config.RecipeRec = RecWrite; write_config(); } fwrite(dst, 1, recipe_hdr.recsize, n); RecWrite++; } RecRead++; } fclose(o); fclose(n); rename("/spiffs/etc/recipe.conf", "/spiffs/etc/recipe.old"); rename("/spiffs/etc/recipe.new", "/spiffs/etc/recipe.conf"); unlink("/spiffs/etc/recipe.old"); ESP_LOGI(TAG, "Deleted recipe %d", RecNo); }