Merge PR #494: Split thing cache into individual files
This commit is contained in:
commit
443dbfb42b
@ -207,7 +207,6 @@ void DebugReportGenerator::saveConfigs()
|
|||||||
// Start copy files setting files
|
// Start copy files setting files
|
||||||
copyFileToReportDirectory(NymeaSettings(NymeaSettings::SettingsRoleGlobal).fileName(), "config");
|
copyFileToReportDirectory(NymeaSettings(NymeaSettings::SettingsRoleGlobal).fileName(), "config");
|
||||||
copyFileToReportDirectory(NymeaSettings(NymeaSettings::SettingsRoleThings).fileName(), "config");
|
copyFileToReportDirectory(NymeaSettings(NymeaSettings::SettingsRoleThings).fileName(), "config");
|
||||||
copyFileToReportDirectory(NymeaSettings(NymeaSettings::SettingsRoleThingStates).fileName(), "config");
|
|
||||||
copyFileToReportDirectory(NymeaSettings(NymeaSettings::SettingsRoleRules).fileName(), "config");
|
copyFileToReportDirectory(NymeaSettings(NymeaSettings::SettingsRoleRules).fileName(), "config");
|
||||||
copyFileToReportDirectory(NymeaSettings(NymeaSettings::SettingsRolePlugins).fileName(), "config");
|
copyFileToReportDirectory(NymeaSettings(NymeaSettings::SettingsRolePlugins).fileName(), "config");
|
||||||
copyFileToReportDirectory(NymeaSettings(NymeaSettings::SettingsRoleTags).fileName(), "config");
|
copyFileToReportDirectory(NymeaSettings(NymeaSettings::SettingsRoleTags).fileName(), "config");
|
||||||
|
|||||||
@ -227,34 +227,6 @@ HttpReply *DebugServerHandler::processDebugRequest(const QString &requestPath, c
|
|||||||
return reply;
|
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")) {
|
if (requestPath.startsWith("/debug/settings/plugins")) {
|
||||||
QString settingsFileName = NymeaSettings(NymeaSettings::SettingsRolePlugins).fileName();
|
QString settingsFileName = NymeaSettings(NymeaSettings::SettingsRolePlugins).fileName();
|
||||||
@ -1391,56 +1363,6 @@ QByteArray DebugServerHandler::createDebugXmlDocument()
|
|||||||
writer.writeEndElement(); // div download-row
|
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
|
// Download row rules
|
||||||
writer.writeStartElement("div");
|
writer.writeStartElement("div");
|
||||||
writer.writeAttribute("class", "download-row");
|
writer.writeAttribute("class", "download-row");
|
||||||
|
|||||||
@ -845,8 +845,7 @@ Thing::ThingError ThingManagerImplementation::removeConfiguredThing(const ThingI
|
|||||||
settings.remove("");
|
settings.remove("");
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
|
||||||
NymeaSettings stateCache(NymeaSettings::SettingsRoleThingStates);
|
QFile::remove(statesCacheFile(thingId));
|
||||||
stateCache.remove(thingId.toString());
|
|
||||||
|
|
||||||
foreach (const IOConnectionId &ioConnectionId, m_ioConnections.keys()) {
|
foreach (const IOConnectionId &ioConnectionId, m_ioConnections.keys()) {
|
||||||
IOConnection ioConnection = m_ioConnections.value(ioConnectionId);
|
IOConnection ioConnection = m_ioConnections.value(ioConnectionId);
|
||||||
@ -1792,12 +1791,12 @@ void ThingManagerImplementation::onLoaded()
|
|||||||
|
|
||||||
void ThingManagerImplementation::cleanupThingStateCache()
|
void ThingManagerImplementation::cleanupThingStateCache()
|
||||||
{
|
{
|
||||||
NymeaSettings settings(NymeaSettings::SettingsRoleThingStates);
|
QDir dir(NymeaSettings::cachePath() + "/thingstates/");
|
||||||
foreach (const QString &entry, settings.childGroups()) {
|
foreach (const QFileInfo &entry, dir.entryList()) {
|
||||||
ThingId thingId(entry);
|
ThingId thingId(entry.baseName());
|
||||||
if (!m_configuredThings.contains(thingId)) {
|
if (!m_configuredThings.contains(thingId)) {
|
||||||
qCDebug(dcThingManager()) << "Thing ID" << thingId << "not found in configured things. Cleaning up stale thing state cache.";
|
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?";
|
qCWarning(dcThingManager()) << "Invalid thing id in state change. Not forwarding event. Thing setup not complete yet?";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
storeThingState(thing, stateTypeId);
|
if (thing->thingClass().getStateType(stateTypeId).cached()) {
|
||||||
|
storeThingState(thing, stateTypeId);
|
||||||
|
}
|
||||||
|
|
||||||
emit thingStateChanged(thing, stateTypeId, value, minValue, maxValue);
|
emit thingStateChanged(thing, stateTypeId, value, minValue, maxValue);
|
||||||
|
|
||||||
@ -2100,10 +2101,21 @@ void ThingManagerImplementation::postSetupThing(Thing *thing)
|
|||||||
plugin->postSetupThing(thing);
|
plugin->postSetupThing(thing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString ThingManagerImplementation::statesCacheFile(const ThingId &thingId)
|
||||||
|
{
|
||||||
|
return NymeaSettings::cachePath() + "/thingstates/" + thingId.toString().remove(QRegExp("[{}]")) + ".cache";
|
||||||
|
}
|
||||||
|
|
||||||
void ThingManagerImplementation::loadThingStates(Thing *thing)
|
void ThingManagerImplementation::loadThingStates(Thing *thing)
|
||||||
{
|
{
|
||||||
NymeaSettings settings(NymeaSettings::SettingsRoleThingStates);
|
QSettings *settings = nullptr;
|
||||||
settings.beginGroup(thing->id().toString());
|
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());
|
ThingClass thingClass = m_supportedThings.value(thing->thingClassId());
|
||||||
foreach (const StateType &stateType, thingClass.stateTypes()) {
|
foreach (const StateType &stateType, thingClass.stateTypes()) {
|
||||||
QVariant value = stateType.defaultValue();
|
QVariant value = stateType.defaultValue();
|
||||||
@ -2111,15 +2123,15 @@ void ThingManagerImplementation::loadThingStates(Thing *thing)
|
|||||||
QVariant maxValue = stateType.maxValue();
|
QVariant maxValue = stateType.maxValue();
|
||||||
|
|
||||||
if (stateType.cached()) {
|
if (stateType.cached()) {
|
||||||
if (settings.childGroups().contains(stateType.id().toString())) {
|
if (settings->childGroups().contains(stateType.id().toString())) {
|
||||||
settings.beginGroup(stateType.id().toString());
|
settings->beginGroup(stateType.id().toString());
|
||||||
value = settings.value("value");
|
value = settings->value("value");
|
||||||
minValue = settings.value("minValue");
|
minValue = settings->value("minValue");
|
||||||
maxValue = settings.value("maxValue");
|
maxValue = settings->value("maxValue");
|
||||||
settings.endGroup();
|
settings->endGroup();
|
||||||
} else if (settings.contains(stateType.id().toString())) {
|
} else if (settings->contains(stateType.id().toString())) {
|
||||||
// Migration from < 0.30
|
// Migration from < 0.30
|
||||||
value = settings.value(stateType.id().toString());
|
value = settings->value(stateType.id().toString());
|
||||||
}
|
}
|
||||||
value.convert(stateType.type());
|
value.convert(stateType.type());
|
||||||
minValue.convert(stateType.type());
|
minValue.convert(stateType.type());
|
||||||
@ -2130,7 +2142,7 @@ void ThingManagerImplementation::loadThingStates(Thing *thing)
|
|||||||
thing->setStateMinMaxValues(stateType.id(), minValue, maxValue);
|
thing->setStateMinMaxValues(stateType.id(), minValue, maxValue);
|
||||||
thing->setStateValueFilter(stateType.id(), stateType.filter());
|
thing->setStateValueFilter(stateType.id(), stateType.filter());
|
||||||
}
|
}
|
||||||
settings.endGroup();
|
delete settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThingManagerImplementation::storeIOConnections()
|
void ThingManagerImplementation::storeIOConnections()
|
||||||
@ -2295,19 +2307,20 @@ void ThingManagerImplementation::storeThingStates(Thing *thing)
|
|||||||
{
|
{
|
||||||
ThingClass thingClass = m_supportedThings.value(thing->thingClassId());
|
ThingClass thingClass = m_supportedThings.value(thing->thingClassId());
|
||||||
foreach (const StateType &stateType, thingClass.stateTypes()) {
|
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)
|
void ThingManagerImplementation::storeThingState(Thing *thing, const StateTypeId &stateTypeId)
|
||||||
{
|
{
|
||||||
NymeaSettings settings(NymeaSettings::SettingsRoleThingStates);
|
QSettings settings(statesCacheFile(thing->id()), QSettings::IniFormat);
|
||||||
settings.beginGroup(thing->id().toString());
|
qCDebug(dcThingManager()) << "Caching state:" << thing->name() << thing->thingClass().stateTypes().findById(stateTypeId).name();
|
||||||
settings.beginGroup(stateTypeId.toString());
|
settings.beginGroup(stateTypeId.toString());
|
||||||
settings.setValue("value", thing->stateValue(stateTypeId));
|
settings.setValue("value", thing->stateValue(stateTypeId));
|
||||||
settings.setValue("minValue", thing->state(stateTypeId).minValue());
|
settings.setValue("minValue", thing->state(stateTypeId).minValue());
|
||||||
settings.setValue("maxValue", thing->state(stateTypeId).maxValue());
|
settings.setValue("maxValue", thing->state(stateTypeId).maxValue());
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
settings.endGroup();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -162,6 +162,7 @@ private:
|
|||||||
void trySetupThing(Thing *thing);
|
void trySetupThing(Thing *thing);
|
||||||
void registerThing(Thing *thing);
|
void registerThing(Thing *thing);
|
||||||
void postSetupThing(Thing *thing);
|
void postSetupThing(Thing *thing);
|
||||||
|
QString statesCacheFile(const ThingId &thingId);
|
||||||
void storeThingStates(Thing *thing);
|
void storeThingStates(Thing *thing);
|
||||||
void storeThingState(Thing *thing, const StateTypeId &stateTypeId);
|
void storeThingState(Thing *thing, const StateTypeId &stateTypeId);
|
||||||
void loadThingStates(Thing *thing);
|
void loadThingStates(Thing *thing);
|
||||||
|
|||||||
@ -114,9 +114,6 @@ NymeaSettings::NymeaSettings(const SettingsRole &role, QObject *parent):
|
|||||||
case SettingsRoleGlobal:
|
case SettingsRoleGlobal:
|
||||||
fileName = "nymead.conf";
|
fileName = "nymead.conf";
|
||||||
break;
|
break;
|
||||||
case SettingsRoleThingStates:
|
|
||||||
fileName = "thingstates.conf";
|
|
||||||
break;
|
|
||||||
case SettingsRoleTags:
|
case SettingsRoleTags:
|
||||||
fileName = "tags.conf";
|
fileName = "tags.conf";
|
||||||
break;
|
break;
|
||||||
@ -207,6 +204,22 @@ QString NymeaSettings::storagePath()
|
|||||||
return path;
|
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.*/
|
/*! Return a list of all settings keys.*/
|
||||||
QStringList NymeaSettings::allKeys() const
|
QStringList NymeaSettings::allKeys() const
|
||||||
{
|
{
|
||||||
|
|||||||
@ -48,7 +48,6 @@ public:
|
|||||||
SettingsRoleRules,
|
SettingsRoleRules,
|
||||||
SettingsRolePlugins,
|
SettingsRolePlugins,
|
||||||
SettingsRoleGlobal,
|
SettingsRoleGlobal,
|
||||||
SettingsRoleThingStates,
|
|
||||||
SettingsRoleTags,
|
SettingsRoleTags,
|
||||||
SettingsRoleMqttPolicies,
|
SettingsRoleMqttPolicies,
|
||||||
SettingsRoleIOConnections,
|
SettingsRoleIOConnections,
|
||||||
@ -66,6 +65,7 @@ public:
|
|||||||
static QString settingsPath();
|
static QString settingsPath();
|
||||||
static QString translationsPath();
|
static QString translationsPath();
|
||||||
static QString storagePath();
|
static QString storagePath();
|
||||||
|
static QString cachePath();
|
||||||
|
|
||||||
// forwarded QSettings methods
|
// forwarded QSettings methods
|
||||||
QStringList allKeys() const;
|
QStringList allKeys() const;
|
||||||
|
|||||||
@ -64,8 +64,8 @@ void NymeaTestBase::initTestCase(const QString &loggingRules)
|
|||||||
thingSettings.clear();
|
thingSettings.clear();
|
||||||
NymeaSettings pluginSettings(NymeaSettings::SettingsRolePlugins);
|
NymeaSettings pluginSettings(NymeaSettings::SettingsRolePlugins);
|
||||||
pluginSettings.clear();
|
pluginSettings.clear();
|
||||||
NymeaSettings statesSettings(NymeaSettings::SettingsRoleThingStates);
|
QDir dir(NymeaSettings::cachePath() + "/thingstates/");
|
||||||
statesSettings.clear();
|
dir.removeRecursively();
|
||||||
|
|
||||||
// Reset to default settings
|
// Reset to default settings
|
||||||
NymeaSettings nymeadSettings(NymeaSettings::SettingsRoleGlobal);
|
NymeaSettings nymeadSettings(NymeaSettings::SettingsRoleGlobal);
|
||||||
|
|||||||
Reference in New Issue
Block a user