From f59292d49188069b96c865525b6edc2cc38f3abb Mon Sep 17 00:00:00 2001 From: Pascal Martin Date: Tue, 29 Dec 2020 13:26:16 -0800 Subject: [PATCH] Save system-wide variable on change --- housesprinkler_config.c | 71 ++++++++++++++++++++++++++++++++++++++-- housesprinkler_config.h | 3 ++ housesprinkler_program.c | 10 +++++- public/backup.json | 2 ++ 4 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 public/backup.json diff --git a/housesprinkler_config.c b/housesprinkler_config.c index b5cbadb..66683b2 100644 --- a/housesprinkler_config.c +++ b/housesprinkler_config.c @@ -63,6 +63,13 @@ * * Get the name of the current configuration file, for informational * purpose (e.g. error messages). + * + * long housesprinkler_config_backup_get (const char *path); + * void housesprinkler_config_backup_set (const char *path, long value); + * + * Read from, and write to, the backup file. This backup file contains + * a handful of saved values that are system-wide and can be changed + * from the user interface. They are all integer type. */ #include @@ -76,6 +83,7 @@ #include #include "houselog.h" + #include "housesprinkler.h" #include "housesprinkler_config.h" @@ -95,18 +103,52 @@ static const char FactoryDefaultsConfigFile[] = "/usr/local/share/house/public/sprinkler/defaults.json"; static int UseFactoryDefaults = 0; +#define BACKUPMAXSIZE 32 + +static ParserToken BackupParsed[BACKUPMAXSIZE]; +static int BackupTokenCount = 0; +static char *BackupText = 0; + +static const char *BackupFile = "/etc/house/sprinklerbkp.json"; + +static const char FactoryBackupFile[] = + "/usr/local/share/house/public/sprinkler/backup.json"; + const char *housesprinkler_config_load (int argc, const char **argv) { struct stat filestat; int fd; - const char *configname; char *newconfig; int i; for (i = 1; i < argc; ++i) { - if (echttp_option_match ("-config=", argv[i], &configname)) - ConfigFile = strdup(configname); + if (echttp_option_match ("-config=", argv[i], &ConfigFile)) continue; + if (echttp_option_match ("-backup=", argv[i], &BackupFile)) continue; + } + + DEBUG ("Loading backup from %s\n", BackupFile); + if (BackupText) echttp_parser_free (BackupText); + BackupText = 0; + BackupTokenCount = 0; + newconfig = echttp_parser_load (BackupFile); + if (!newconfig) { + DEBUG ("Loading backup from %s\n", FactoryBackupFile); + newconfig = echttp_parser_load (FactoryBackupFile); + houselog_event ("SYSTEM", "BACKUP", "LOAD", + "FILE %s", FactoryBackupFile); + } else { + houselog_event ("SYSTEM", "BACKUP", "LOAD", + "FILE %s", BackupFile); + } + if (newconfig) { + BackupText = newconfig; + BackupTokenCount = BACKUPMAXSIZE; + if (echttp_json_parse (BackupText, BackupParsed, &BackupTokenCount)) { + echttp_parser_free (BackupText); + BackupText = 0; + BackupTokenCount = 0; + } } DEBUG ("Loading config from %s\n", ConfigFile); @@ -247,3 +289,26 @@ const char *housesprinkler_config_name (void) { return ConfigFile; } +long housesprinkler_config_backup_get (const char *path) { + + int i = echttp_json_search(BackupParsed, path); + return (i >= 0) ? BackupParsed[i].value.integer : 0; +} + +void housesprinkler_config_backup_set (const char *path, long value) { + + char buffer[1024]; + int i = echttp_json_search(BackupParsed, path); + + if (i < 0) return; + BackupParsed[i].value.integer = value; + + if (echttp_json_format (BackupParsed, BackupTokenCount, + buffer, sizeof(buffer), 0)) return; + + int fd = open (BackupFile, O_WRONLY|O_TRUNC|O_CREAT, 0777); + if (fd < 0) return; + write (fd, buffer, strlen(buffer)); + close(fd); +} + diff --git a/housesprinkler_config.h b/housesprinkler_config.h index 43b10b2..4d3cee8 100644 --- a/housesprinkler_config.h +++ b/housesprinkler_config.h @@ -38,3 +38,6 @@ int housesprinkler_config_object (int parent, const char *path); const char *housesprinkler_config_name (void); +long housesprinkler_config_backup_get (const char *path); +void housesprinkler_config_backup_set (const char *path, long value); + diff --git a/housesprinkler_program.c b/housesprinkler_program.c index 04f548b..5e9f8ec 100644 --- a/housesprinkler_program.c +++ b/housesprinkler_program.c @@ -299,6 +299,9 @@ void housesprinkler_program_refresh (void) { Programs[i].name, Programs[i].start.hour, Programs[i].start.minute, count); } } + + SprinklerState = housesprinkler_config_backup_get (".on"); + ProgramRainDelay = (time_t)housesprinkler_config_backup_get (".raindelay"); } void housesprinkler_program_index (int state) { @@ -315,7 +318,10 @@ void housesprinkler_program_set_index void housesprinkler_program_rain (int enabled) { ProgramRainEnabled = enabled; - if (!enabled) ProgramRainDelay; + if (!enabled) { + ProgramRainDelay = 0; + housesprinkler_config_backup_set (".raindelay", 0); + } } void housesprinkler_program_set_rain (int delay) { @@ -337,6 +343,7 @@ void housesprinkler_program_set_rain (int delay) { // This is an extension to the ongoing rain delay period. ProgramRainDelay += delay; } + housesprinkler_config_backup_set (".raindelay", (long)ProgramRainDelay); } static void housesprinkler_program_activate @@ -513,6 +520,7 @@ void housesprinkler_program_switch (void) { time_t now = time(0); SprinklerState = !SprinklerState; houselog_event ("PROGRAM", "SWITCH", SprinklerState?"ON":"OFF", ""); + housesprinkler_config_backup_set (".on", SprinklerState); } int housesprinkler_program_status (char *buffer, int size) { diff --git a/public/backup.json b/public/backup.json new file mode 100644 index 0000000..2cdefd2 --- /dev/null +++ b/public/backup.json @@ -0,0 +1,2 @@ +{"on":1,"raindelay":0} +