mirror of https://github.com/nymea/nymea.git
Split thing state cache into individual files
parent
28d2f53261
commit
7bfb48feac
|
|
@ -207,7 +207,6 @@ void DebugReportGenerator::saveConfigs()
|
|||
// Start copy files setting files
|
||||
copyFileToReportDirectory(NymeaSettings(NymeaSettings::SettingsRoleGlobal).fileName(), "config");
|
||||
copyFileToReportDirectory(NymeaSettings(NymeaSettings::SettingsRoleThings).fileName(), "config");
|
||||
copyFileToReportDirectory(NymeaSettings(NymeaSettings::SettingsRoleThingStates).fileName(), "config");
|
||||
copyFileToReportDirectory(NymeaSettings(NymeaSettings::SettingsRoleRules).fileName(), "config");
|
||||
copyFileToReportDirectory(NymeaSettings(NymeaSettings::SettingsRolePlugins).fileName(), "config");
|
||||
copyFileToReportDirectory(NymeaSettings(NymeaSettings::SettingsRoleTags).fileName(), "config");
|
||||
|
|
|
|||
|
|
@ -227,34 +227,6 @@ HttpReply *DebugServerHandler::processDebugRequest(const QString &requestPath, c
|
|||
return reply;
|
||||
}
|
||||
|
||||
if (requestPath.startsWith("/debug/settings/thingstates")) {
|
||||
QString settingsFileName = NymeaSettings(NymeaSettings::SettingsRoleThingStates).fileName();
|
||||
qCDebug(dcDebugServer()) << "Loading" << settingsFileName;
|
||||
QFile settingsFile(settingsFileName);
|
||||
if (!settingsFile.exists()) {
|
||||
qCWarning(dcDebugServer()) << "Could not read file for debug download" << settingsFileName << "file does not exist.";
|
||||
HttpReply *reply = HttpReply::createErrorReply(HttpReply::NotFound);
|
||||
reply->setHeader(HttpReply::ContentTypeHeader, "text/html");
|
||||
reply->setPayload(createErrorXmlDocument(HttpReply::NotFound, tr("Could not find file \"%1\".").arg(settingsFileName)));
|
||||
return reply;
|
||||
}
|
||||
|
||||
if (!settingsFile.open(QFile::ReadOnly)) {
|
||||
qCWarning(dcDebugServer()) << "Could not read file for debug download" << settingsFileName;
|
||||
HttpReply *reply = HttpReply::createErrorReply(HttpReply::Forbidden);
|
||||
reply->setHeader(HttpReply::ContentTypeHeader, "text/html");
|
||||
reply->setPayload(createErrorXmlDocument(HttpReply::NotFound, tr("Could not open file \"%1\".").arg(settingsFileName)));
|
||||
return reply;
|
||||
}
|
||||
|
||||
QByteArray settingsFileData = settingsFile.readAll();
|
||||
settingsFile.close();
|
||||
|
||||
HttpReply *reply = HttpReply::createSuccessReply();
|
||||
reply->setHeader(HttpReply::ContentTypeHeader, "text/plain");
|
||||
reply->setPayload(settingsFileData);
|
||||
return reply;
|
||||
}
|
||||
|
||||
if (requestPath.startsWith("/debug/settings/plugins")) {
|
||||
QString settingsFileName = NymeaSettings(NymeaSettings::SettingsRolePlugins).fileName();
|
||||
|
|
@ -1391,56 +1363,6 @@ QByteArray DebugServerHandler::createDebugXmlDocument()
|
|||
writer.writeEndElement(); // div download-row
|
||||
|
||||
|
||||
// Download row thing states
|
||||
writer.writeStartElement("div");
|
||||
writer.writeAttribute("class", "download-row");
|
||||
|
||||
writer.writeStartElement("div");
|
||||
writer.writeAttribute("class", "download-name-column");
|
||||
//: The thing states settings download description of the debug interface
|
||||
writer.writeTextElement("p", tr("Thing states settings"));
|
||||
writer.writeEndElement(); // div download-name-column
|
||||
|
||||
writer.writeStartElement("div");
|
||||
writer.writeAttribute("class", "download-path-column");
|
||||
writer.writeTextElement("p", NymeaSettings(NymeaSettings::SettingsRoleThingStates).fileName());
|
||||
writer.writeEndElement(); // div download-path-column
|
||||
|
||||
writer.writeStartElement("div");
|
||||
writer.writeAttribute("class", "download-button-column");
|
||||
writer.writeStartElement("form");
|
||||
writer.writeAttribute("class", "download-button");
|
||||
writer.writeStartElement("button");
|
||||
writer.writeAttribute("class", "button");
|
||||
writer.writeAttribute("type", "button");
|
||||
if (!QFile::exists(NymeaSettings(NymeaSettings::SettingsRoleThingStates).fileName())) {
|
||||
writer.writeAttribute("disabled", "true");
|
||||
}
|
||||
writer.writeAttribute("onClick", "downloadFile('/debug/settings/thingstates', 'thingstates.conf')");
|
||||
writer.writeCharacters(tr("Download"));
|
||||
writer.writeEndElement(); // button
|
||||
writer.writeEndElement(); // form
|
||||
writer.writeEndElement(); // div download-button-column
|
||||
|
||||
writer.writeStartElement("div");
|
||||
writer.writeAttribute("class", "show-button-column");
|
||||
writer.writeStartElement("form");
|
||||
writer.writeAttribute("class", "show-button");
|
||||
writer.writeStartElement("button");
|
||||
writer.writeAttribute("class", "button");
|
||||
writer.writeAttribute("type", "button");
|
||||
if (!QFile::exists(NymeaSettings(NymeaSettings::SettingsRoleThingStates).fileName())) {
|
||||
writer.writeAttribute("disabled", "true");
|
||||
}
|
||||
writer.writeAttribute("onClick", "showFile('/debug/settings/thingstates')");
|
||||
writer.writeCharacters(tr("Show"));
|
||||
writer.writeEndElement(); // button
|
||||
writer.writeEndElement(); // form
|
||||
writer.writeEndElement(); // div show-button-column
|
||||
|
||||
writer.writeEndElement(); // div download-row
|
||||
|
||||
|
||||
// Download row rules
|
||||
writer.writeStartElement("div");
|
||||
writer.writeAttribute("class", "download-row");
|
||||
|
|
|
|||
|
|
@ -845,8 +845,7 @@ Thing::ThingError ThingManagerImplementation::removeConfiguredThing(const ThingI
|
|||
settings.remove("");
|
||||
settings.endGroup();
|
||||
|
||||
NymeaSettings stateCache(NymeaSettings::SettingsRoleThingStates);
|
||||
stateCache.remove(thingId.toString());
|
||||
QFile::remove(statesCacheFile(thingId));
|
||||
|
||||
foreach (const IOConnectionId &ioConnectionId, m_ioConnections.keys()) {
|
||||
IOConnection ioConnection = m_ioConnections.value(ioConnectionId);
|
||||
|
|
@ -1792,12 +1791,12 @@ void ThingManagerImplementation::onLoaded()
|
|||
|
||||
void ThingManagerImplementation::cleanupThingStateCache()
|
||||
{
|
||||
NymeaSettings settings(NymeaSettings::SettingsRoleThingStates);
|
||||
foreach (const QString &entry, settings.childGroups()) {
|
||||
ThingId thingId(entry);
|
||||
QDir dir(NymeaSettings::cachePath() + "/thingstates/");
|
||||
foreach (const QFileInfo &entry, dir.entryList()) {
|
||||
ThingId thingId(entry.baseName());
|
||||
if (!m_configuredThings.contains(thingId)) {
|
||||
qCDebug(dcThingManager()) << "Thing ID" << thingId << "not found in configured things. Cleaning up stale thing state cache.";
|
||||
settings.remove(entry);
|
||||
QFile::remove(entry.absoluteFilePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1831,7 +1830,9 @@ void ThingManagerImplementation::slotThingStateValueChanged(const StateTypeId &s
|
|||
qCWarning(dcThingManager()) << "Invalid thing id in state change. Not forwarding event. Thing setup not complete yet?";
|
||||
return;
|
||||
}
|
||||
storeThingState(thing, stateTypeId);
|
||||
if (thing->thingClass().getStateType(stateTypeId).cached()) {
|
||||
storeThingState(thing, stateTypeId);
|
||||
}
|
||||
|
||||
emit thingStateChanged(thing, stateTypeId, value, minValue, maxValue);
|
||||
|
||||
|
|
@ -2100,10 +2101,21 @@ void ThingManagerImplementation::postSetupThing(Thing *thing)
|
|||
plugin->postSetupThing(thing);
|
||||
}
|
||||
|
||||
QString ThingManagerImplementation::statesCacheFile(const ThingId &thingId)
|
||||
{
|
||||
return NymeaSettings::cachePath() + "/thingstates/" + thingId.toString().remove(QRegExp("[{}]")) + ".cache";
|
||||
}
|
||||
|
||||
void ThingManagerImplementation::loadThingStates(Thing *thing)
|
||||
{
|
||||
NymeaSettings settings(NymeaSettings::SettingsRoleThingStates);
|
||||
settings.beginGroup(thing->id().toString());
|
||||
QSettings *settings = nullptr;
|
||||
if (QFile::exists(statesCacheFile(thing->id()))) {
|
||||
settings = new QSettings(statesCacheFile(thing->id()), QSettings::IniFormat);
|
||||
} else {
|
||||
// try legacy (<= 0.30 cache)
|
||||
settings = new QSettings(NymeaSettings::settingsPath() + "/thingstates.conf", QSettings::IniFormat);
|
||||
settings->beginGroup(thing->id().toString());
|
||||
}
|
||||
ThingClass thingClass = m_supportedThings.value(thing->thingClassId());
|
||||
foreach (const StateType &stateType, thingClass.stateTypes()) {
|
||||
QVariant value = stateType.defaultValue();
|
||||
|
|
@ -2111,15 +2123,15 @@ void ThingManagerImplementation::loadThingStates(Thing *thing)
|
|||
QVariant maxValue = stateType.maxValue();
|
||||
|
||||
if (stateType.cached()) {
|
||||
if (settings.childGroups().contains(stateType.id().toString())) {
|
||||
settings.beginGroup(stateType.id().toString());
|
||||
value = settings.value("value");
|
||||
minValue = settings.value("minValue");
|
||||
maxValue = settings.value("maxValue");
|
||||
settings.endGroup();
|
||||
} else if (settings.contains(stateType.id().toString())) {
|
||||
if (settings->childGroups().contains(stateType.id().toString())) {
|
||||
settings->beginGroup(stateType.id().toString());
|
||||
value = settings->value("value");
|
||||
minValue = settings->value("minValue");
|
||||
maxValue = settings->value("maxValue");
|
||||
settings->endGroup();
|
||||
} else if (settings->contains(stateType.id().toString())) {
|
||||
// Migration from < 0.30
|
||||
value = settings.value(stateType.id().toString());
|
||||
value = settings->value(stateType.id().toString());
|
||||
}
|
||||
value.convert(stateType.type());
|
||||
minValue.convert(stateType.type());
|
||||
|
|
@ -2130,7 +2142,7 @@ void ThingManagerImplementation::loadThingStates(Thing *thing)
|
|||
thing->setStateMinMaxValues(stateType.id(), minValue, maxValue);
|
||||
thing->setStateValueFilter(stateType.id(), stateType.filter());
|
||||
}
|
||||
settings.endGroup();
|
||||
delete settings;
|
||||
}
|
||||
|
||||
void ThingManagerImplementation::storeIOConnections()
|
||||
|
|
@ -2295,19 +2307,20 @@ void ThingManagerImplementation::storeThingStates(Thing *thing)
|
|||
{
|
||||
ThingClass thingClass = m_supportedThings.value(thing->thingClassId());
|
||||
foreach (const StateType &stateType, thingClass.stateTypes()) {
|
||||
storeThingState(thing, stateType.id());
|
||||
if (stateType.cached()) {
|
||||
storeThingState(thing, stateType.id());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ThingManagerImplementation::storeThingState(Thing *thing, const StateTypeId &stateTypeId)
|
||||
{
|
||||
NymeaSettings settings(NymeaSettings::SettingsRoleThingStates);
|
||||
settings.beginGroup(thing->id().toString());
|
||||
QSettings settings(statesCacheFile(thing->id()), QSettings::IniFormat);
|
||||
qCDebug(dcThingManager()) << "Caching state:" << thing->name() << thing->thingClass().stateTypes().findById(stateTypeId).name();
|
||||
settings.beginGroup(stateTypeId.toString());
|
||||
settings.setValue("value", thing->stateValue(stateTypeId));
|
||||
settings.setValue("minValue", thing->state(stateTypeId).minValue());
|
||||
settings.setValue("maxValue", thing->state(stateTypeId).maxValue());
|
||||
settings.endGroup();
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -162,6 +162,7 @@ private:
|
|||
void trySetupThing(Thing *thing);
|
||||
void registerThing(Thing *thing);
|
||||
void postSetupThing(Thing *thing);
|
||||
QString statesCacheFile(const ThingId &thingId);
|
||||
void storeThingStates(Thing *thing);
|
||||
void storeThingState(Thing *thing, const StateTypeId &stateTypeId);
|
||||
void loadThingStates(Thing *thing);
|
||||
|
|
|
|||
|
|
@ -114,9 +114,6 @@ NymeaSettings::NymeaSettings(const SettingsRole &role, QObject *parent):
|
|||
case SettingsRoleGlobal:
|
||||
fileName = "nymead.conf";
|
||||
break;
|
||||
case SettingsRoleThingStates:
|
||||
fileName = "thingstates.conf";
|
||||
break;
|
||||
case SettingsRoleTags:
|
||||
fileName = "tags.conf";
|
||||
break;
|
||||
|
|
@ -207,6 +204,22 @@ QString NymeaSettings::storagePath()
|
|||
return path;
|
||||
}
|
||||
|
||||
QString NymeaSettings::cachePath()
|
||||
{
|
||||
QString path;
|
||||
QString organisationName = QCoreApplication::instance()->organizationName();
|
||||
if (!qEnvironmentVariableIsEmpty("SNAP")) {
|
||||
path = QString(qgetenv("SNAP_DATA"));
|
||||
} else if (organisationName == "nymea-test") {
|
||||
path = "/tmp/" + organisationName;
|
||||
} else if (NymeaSettings::isRoot()) {
|
||||
path = "/var/cache/" + organisationName;
|
||||
} else {
|
||||
path = QDir::homePath() + "/.cache/" + organisationName;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
/*! Return a list of all settings keys.*/
|
||||
QStringList NymeaSettings::allKeys() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@ public:
|
|||
SettingsRoleRules,
|
||||
SettingsRolePlugins,
|
||||
SettingsRoleGlobal,
|
||||
SettingsRoleThingStates,
|
||||
SettingsRoleTags,
|
||||
SettingsRoleMqttPolicies,
|
||||
SettingsRoleIOConnections,
|
||||
|
|
@ -66,6 +65,7 @@ public:
|
|||
static QString settingsPath();
|
||||
static QString translationsPath();
|
||||
static QString storagePath();
|
||||
static QString cachePath();
|
||||
|
||||
// forwarded QSettings methods
|
||||
QStringList allKeys() const;
|
||||
|
|
|
|||
|
|
@ -64,8 +64,8 @@ void NymeaTestBase::initTestCase(const QString &loggingRules)
|
|||
thingSettings.clear();
|
||||
NymeaSettings pluginSettings(NymeaSettings::SettingsRolePlugins);
|
||||
pluginSettings.clear();
|
||||
NymeaSettings statesSettings(NymeaSettings::SettingsRoleThingStates);
|
||||
statesSettings.clear();
|
||||
QDir dir(NymeaSettings::cachePath() + "/thingstates/");
|
||||
dir.removeRecursively();
|
||||
|
||||
// Reset to default settings
|
||||
NymeaSettings nymeadSettings(NymeaSettings::SettingsRoleGlobal);
|
||||
|
|
|
|||
Loading…
Reference in New Issue