Retry setup if it fails at startup (e.g. network isn't up yet or similar)

pull/293/head
Michael Zanetti 2020-05-13 22:55:29 +02:00
parent a0add78af0
commit 6aaab68cdc
2 changed files with 33 additions and 20 deletions

View File

@ -1565,25 +1565,7 @@ void ThingManagerImplementation::loadConfiguredThings()
}
Q_ASSERT(thing != nullptr);
thing->setSetupStatus(Thing::ThingSetupStatusInProgress, Thing::ThingErrorNoError);
ThingSetupInfo *info = setupThing(thing);
// Set receiving object to "thing" because at startup we load it in any case, knowing that it worked at
// some point. However, it'll be marked as non-working until the setup succeeds so the user might delete
// it in the meantime... In that case we don't want to call postsetup on it.
connect(info, &ThingSetupInfo::finished, thing, [this, info](){
if (info->status() != Thing::ThingErrorNoError) {
qCWarning(dcThingManager()) << "Error setting up thing" << info->thing()->name() << info->thing()->id().toString() << info->status() << info->displayMessage();
info->thing()->setSetupStatus(Thing::ThingSetupStatusFailed, info->status(), info->displayMessage());
emit thingChanged(info->thing());
return;
}
qCDebug(dcThingManager()) << "Setup complete for thing" << info->thing();
info->thing()->setSetupStatus(Thing::ThingSetupStatusComplete, Thing::ThingErrorNoError);
emit thingChanged(info->thing());
postSetupThing(info->thing());
});
trySetupThing(thing);
}
loadIOConnections();
@ -2101,6 +2083,37 @@ QVariant ThingManagerImplementation::mapValue(const QVariant &value, const State
return toValue;
}
void ThingManagerImplementation::trySetupThing(Thing *thing)
{
thing->setSetupStatus(Thing::ThingSetupStatusInProgress, Thing::ThingErrorNoError);
ThingSetupInfo *info = setupThing(thing);
// Set receiving object to "thing" because at startup we load it in any case, knowing that it worked at
// some point. However, it'll be marked as non-working until the setup succeeds so the user might delete
// it in the meantime... In that case we don't want to call postsetup on it.
connect(info, &ThingSetupInfo::finished, thing, [this, info, thing](){
if (info->status() != Thing::ThingErrorNoError) {
qCWarning(dcThingManager()) << "Error setting up thing" << info->thing()->name() << info->thing()->id().toString() << info->status() << info->displayMessage();
info->thing()->setSetupStatus(Thing::ThingSetupStatusFailed, info->status(), info->displayMessage());
emit thingChanged(info->thing());
// We know this used to work at some point... try again in a bit unless we don't have a plugin for it...
if (info->status() != Thing::ThingErrorPluginNotFound) {
QTimer::singleShot(10000, thing, [this, thing]() {
trySetupThing(thing);
});
}
return;
}
qCDebug(dcThingManager()) << "Setup complete for thing" << info->thing();
info->thing()->setSetupStatus(Thing::ThingSetupStatusComplete, Thing::ThingErrorNoError);
emit thingChanged(info->thing());
postSetupThing(info->thing());
});
}
void ThingManagerImplementation::storeThingStates(Thing *thing)
{
NymeaSettings settings(NymeaSettings::SettingsRoleThingStates);

View File

@ -155,11 +155,11 @@ private:
ThingSetupInfo *reconfigureThingInternal(Thing *thing, const ParamList &params, const QString &name = QString());
ThingSetupInfo *setupThing(Thing *thing);
void postSetupThing(Thing *thing);
void trySetupThing(Thing *thing);
void storeThingStates(Thing *thing);
void loadThingStates(Thing *thing);
void storeIOConnections();
void loadIOConnections();
void syncIOConnection(Thing *inputThing, const StateTypeId &stateTypeId);
QVariant mapValue(const QVariant &value, const StateType &fromStateType, const StateType &toStateType, bool inverted) const;