telldus/driver/libtelldus-core/SettingsConfuse.cpp
2009-09-28 19:15:37 +00:00

363 lines
8.3 KiB
C++

//
// C++ Implementation: telldussettingsconfuse
//
// Description:
//
//
// Author: Micke Prag <micke.prag@telldus.se>, (C) 2008
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "Settings.h"
#include <confuse.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
class privateVars {
public:
cfg_t *cfg;
cfg_t *var_cfg;
};
bool readConfig(cfg_t **cfg);
bool readVarConfig(cfg_t **cfg);
const char* CONFIG_FILE = "/etc/tellstick.conf";
const char* VAR_CONFIG_FILE = "/var/state/telldus-core.conf";
/*
* Constructor
*/
Settings::Settings(void)
{
d = new privateVars();
readConfig(&d->cfg);
readVarConfig(&d->var_cfg);
}
/*
* Destructor
*/
Settings::~Settings(void)
{
if (d->cfg > 0) {
cfg_free(d->cfg);
}
if (d->var_cfg > 0) {
cfg_free(d->var_cfg);
}
delete d;
}
/*
* Return a setting
*/
std::string Settings::getSetting(const std::string &strName) const {
if (d->cfg > 0) {
return cfg_getstr(d->cfg, strName.c_str());
}
return "";
}
/*
* Return the number of stored devices
*/
int Settings::getNumberOfDevices(void) const {
if (d->cfg > 0) {
return cfg_size(d->cfg, "device");
}
return 0;
}
int Settings::getDeviceId(int intDeviceIndex) const {
if (intDeviceIndex >= getNumberOfDevices()) { //Out of bounds
return -1;
}
cfg_t *cfg_device = cfg_getnsec(d->cfg, "device", intDeviceIndex);
int id = cfg_getint(cfg_device, "id");
return id;
}
/*
* Add a new device
*/
int Settings::addDevice(){
int intDeviceId = getNextDeviceId();
FILE *fp = fopen(CONFIG_FILE, "w");
cfg_print(d->cfg, fp); //Print the config-file
fprintf(fp, "device {\n id=%d\n}\n", intDeviceId); //Print the new device
fclose(fp);
//Re-read config-file
cfg_free(d->cfg);
readConfig(&d->cfg);
return intDeviceId;
}
/*
* Get next available device id
*/
int Settings::getNextDeviceId() const {
int intDeviceId = 0;
cfg_t *cfg_device;
for (int i = 0; i < cfg_size(d->cfg, "device"); ++i) {
cfg_device = cfg_getnsec(d->cfg, "device", i);
if (cfg_getint(cfg_device, "id") >= intDeviceId) {
intDeviceId = cfg_getint(cfg_device, "id");
}
}
intDeviceId++;
return intDeviceId;
}
/*
* Remove a device
*/
bool Settings::removeDevice(int intDeviceId){
bool blnSuccess = true;
FILE *fp = fopen(CONFIG_FILE, "w");
// Print all opts
for(int i = 0; d->cfg->opts[i].name; i++) {
// Check if it isn't a device section
if (strcmp(d->cfg->opts[i].name, "device") != 0) {
cfg_opt_print(&d->cfg->opts[i], fp);
} else {
// Print all sections except the one to remove
cfg_t *cfg_device;
for (int i = 0; i < cfg_size(d->cfg, "device"); ++i) {
cfg_device = cfg_getnsec(d->cfg, "device", i);
if (cfg_getint(cfg_device, "id") != intDeviceId) { //This isn't the one to skip
fprintf(fp, "device {\n");
cfg_print_indent(cfg_device, fp, 1);
fprintf(fp, "}\n");
}
}
}
}
fclose(fp);
//Re-read config-file
cfg_free(d->cfg);
readConfig(&d->cfg);
return blnSuccess;
}
bool Settings::setDeviceState( int intDeviceId, int intDeviceState, const std::string &strDeviceStateValue ) {
if (d->var_cfg == 0) {
return false;
}
cfg_t *cfg_device;
for (int i = 0; i < cfg_size(d->var_cfg, "device"); ++i) {
cfg_device = cfg_getnsec(d->var_cfg, "device", i);
int deviceId = atoi(cfg_title(cfg_device));
if (deviceId == intDeviceId) {
cfg_setint(cfg_device, "state", intDeviceState);
cfg_setstr(cfg_device, "stateValue", strDeviceStateValue.c_str());
FILE *fp = fopen(VAR_CONFIG_FILE, "w");
cfg_print(d->var_cfg, fp);
fclose(fp);
return true;
}
}
// The device is not found in the file, we must create it manualy...
FILE *fp = fopen(VAR_CONFIG_FILE, "w");
cfg_print(d->var_cfg, fp); //Print the config-file
fprintf(fp, "device %d {\n}\n", intDeviceId); //Print the new device
fclose(fp);
//Re-read config-file
cfg_free(d->var_cfg);
readVarConfig(&d->var_cfg);
return false;
}
int Settings::getDeviceState( int intDeviceId ) const {
if (d->var_cfg == 0) {
return false;
}
cfg_t *cfg_device;
for (int i = 0; i < cfg_size(d->var_cfg, "device"); ++i) {
cfg_device = cfg_getnsec(d->var_cfg, "device", i);
int deviceId = atoi(cfg_title(cfg_device));
if (deviceId == intDeviceId) {
return cfg_getint(cfg_device, "state");
}
}
return TELLSTICK_TURNOFF;
}
std::string Settings::getDeviceStateValue( int intDeviceId ) const {
if (d->var_cfg == 0) {
return false;
}
cfg_t *cfg_device;
for (int i = 0; i < cfg_size(d->var_cfg, "device"); ++i) {
cfg_device = cfg_getnsec(d->var_cfg, "device", i);
int deviceId = atoi(cfg_title(cfg_device));
if (deviceId == intDeviceId) {
char *value = cfg_getstr(cfg_device, "stateValue");
return value;
}
}
return "";
}
std::string Settings::getStringSetting(int intDeviceId, const std::string &name, bool parameter) const {
if (d->cfg == 0) {
return "";
}
cfg_t *cfg_device;
for (int i = 0; i < cfg_size(d->cfg, "device"); ++i) {
cfg_device = cfg_getnsec(d->cfg, "device", i);
if (cfg_getint(cfg_device, "id") == intDeviceId) {
if (parameter) {
cfg_device = cfg_getsec(cfg_device, "parameters");
}
char *setting = cfg_getstr(cfg_device, name.c_str());
if (setting == 0) { //The parameter does not exists
return "";
}
return setting;
}
}
return "";
}
bool Settings::setStringSetting(int intDeviceId, const std::string &name, const std::string &value, bool parameter) {
if (d->cfg == 0) {
return false;
}
cfg_t *cfg_device;
for (int i = 0; i < cfg_size(d->cfg, "device"); ++i) {
cfg_device = cfg_getnsec(d->cfg, "device", i);
if (cfg_getint(cfg_device, "id") == intDeviceId) {
if (parameter) {
cfg_t *cfg_parameters = cfg_getsec(cfg_device, "parameters");
cfg_setstr(cfg_parameters, name.c_str(), value.c_str());
} else {
cfg_setstr(cfg_device, name.c_str(), value.c_str());
}
FILE *fp = fopen(CONFIG_FILE, "w");
cfg_print(d->cfg, fp);
fclose(fp);
return true;
}
}
return false;
}
int Settings::getIntSetting(int intDeviceId, const std::string &name, bool parameter) const {
if (d->cfg == 0) {
return 0;
}
cfg_t *cfg_device;
for(int i = 0; i < cfg_size(d->cfg, "device"); ++i) {
cfg_device = cfg_getnsec(d->cfg, "device", i);
if (cfg_getint(cfg_device, "id") == intDeviceId) {
if (parameter) {
cfg_device = cfg_getsec(cfg_device, "parameters");
}
return cfg_getint(cfg_device, name.c_str());
}
}
return 0;
}
bool Settings::setIntSetting(int intDeviceId, const std::string &name, int value, bool parameter) {
if (d->cfg == 0) {
return false;
}
cfg_t *cfg_device;
for (int i = 0; i < cfg_size(d->cfg, "device"); ++i) {
cfg_device = cfg_getnsec(d->cfg, "device", i);
if (cfg_getint(cfg_device, "id") == intDeviceId) {
if (parameter) {
cfg_t *cfg_parameters = cfg_getsec(cfg_device, "parameters");
cfg_setint(cfg_parameters, name.c_str(), value);
} else {
cfg_setint(cfg_device, name.c_str(), value);
}
FILE *fp = fopen(CONFIG_FILE, "w");
cfg_print(d->cfg, fp);
fclose(fp);
return true;
}
}
return false;
}
bool readConfig(cfg_t **cfg) {
cfg_opt_t controller_opts[] = {
CFG_INT("id", -1, CFGF_NONE),
};
cfg_opt_t device_parameter_opts[] = {
//Groups
CFG_STR("devices", 0, CFGF_NONE),
CFG_STR("house", 0, CFGF_NONE),
CFG_STR("unit", 0, CFGF_NONE),
CFG_STR("code", 0, CFGF_NONE),
CFG_STR("system", 0, CFGF_NONE),
CFG_STR("units", 0, CFGF_NONE),
CFG_STR("fade", 0, CFGF_NONE),
CFG_END()
};
cfg_opt_t device_opts[] = {
CFG_INT("id", -1, CFGF_NONE),
CFG_STR("name", "Unnamed", CFGF_NONE),
CFG_INT("controller", 0, CFGF_NONE),
CFG_STR("protocol", "arctech", CFGF_NONE),
CFG_STR("model", "", CFGF_NONE),
CFG_SEC("parameters", device_parameter_opts, CFGF_NONE),
CFG_END()
};
cfg_opt_t opts[] = {
CFG_STR("deviceNode", "/dev/tellstick", CFGF_NONE),
CFG_SEC("device", device_opts, CFGF_MULTI),
CFG_END()
};
(*cfg) = cfg_init(opts, CFGF_NOCASE);
if (cfg_parse((*cfg), CONFIG_FILE) == CFG_PARSE_ERROR) {
(*cfg) = 0;
return false;
}
return true;
}
bool readVarConfig(cfg_t **cfg) {
cfg_opt_t device_opts[] = {
CFG_INT("state", 0, CFGF_NONE),
CFG_STR("stateValue", "", CFGF_NONE),
CFG_END()
};
cfg_opt_t opts[] = {
CFG_SEC("device", device_opts, CFGF_MULTI | CFGF_TITLE),
CFG_END()
};
(*cfg) = cfg_init(opts, CFGF_NOCASE);
if (cfg_parse((*cfg), VAR_CONFIG_FILE) == CFG_PARSE_ERROR) {
(*cfg) = 0;
return false;
}
return true;
}