main/config.c

Sat, 31 Jul 2021 15:44:20 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Sat, 31 Jul 2021 15:44:20 +0200
changeset 119
1cef3c25426b
parent 103
1885d0c75c48
child 120
afd58d4c7b5b
permissions
-rw-r--r--

Version 0.3.19. Real sensors and code cleanup.

/**
 * @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]);
	config.xap_ssid[0] = '\0';
	config.xap_pwd[0] = '\0';
	config.xap_channel = 0;
	config.xap_ssid_hidden = 0;
	config.xap_bandwidth = 0;
	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;
	equipment.Hendi = false;
	equipment.RampPower = 100;
	equipment.Max_watt = 2750;
	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 1
	if (equipment_hdr.version < EQUIPMENT_VERSION) {
	    uint32_t	oldsize = equipment_hdr.recsize;
	    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));
	    // Update the header with new sizes
            equipment_hdr.version = EQUIPMENT_VERSION;
            equipment_hdr.hdrsize = sizeof(equipment_hdr);
            equipment_hdr.recsize = sizeof(equipment);
            bytes = fwrite(dst, 1, sizeof(equipment_hdr), nf);

            dst = (uint8_t*)&equipment;
            while ((bytes = fread(dst, 1, oldsize, f))) {
                // Upgrade data here
		equipment.Hendi = false;
		equipment.RampPower = equipment.BoilPower;
		equipment.Max_watt = 3000;
                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));
                }
            }
            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");
	    dst = (uint8_t*)&equipment_hdr;
	    fread(dst, 1, sizeof(equipment_hdr), f);
	}
#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");
}



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);
}

mercurial