Re-add grace period and introduce cached reachable state over nymea restarts
parent
9828e6ec11
commit
2a0fbe90f8
|
|
@ -120,41 +120,59 @@ void IntegrationPluginNetworkDetector::setupThing(ThingSetupInfo *info)
|
|||
return;
|
||||
}
|
||||
|
||||
// Handle reconfigure
|
||||
if (m_monitors.contains(thing)) {
|
||||
hardwareManager()->networkDeviceDiscovery()->unregisterMonitor(m_monitors.take(thing));
|
||||
}
|
||||
|
||||
NetworkDeviceMonitor *monitor = hardwareManager()->networkDeviceDiscovery()->registerMonitor(macAddress);
|
||||
connect(monitor, &NetworkDeviceMonitor::reachableChanged, this, [=](bool reachable){
|
||||
qCDebug(dcNetworkDetector()) << thing << "reachable changed to" << reachable;
|
||||
thing->setStateValue(networkDeviceIsPresentStateTypeId, reachable);
|
||||
});
|
||||
|
||||
connect(monitor, &NetworkDeviceMonitor::lastSeenChanged, this, [=](const QDateTime &lastSeen){
|
||||
QDateTime minuteBased = QDateTime::fromMSecsSinceEpoch((monitor->lastSeen().toMSecsSinceEpoch() / 60000) * 60000);
|
||||
qCDebug(dcNetworkDetector()) << thing << "last seen changed to" << lastSeen.toString() << minuteBased.toString();
|
||||
thing->setStateValue(networkDeviceLastSeenTimeStateTypeId, minuteBased.toMSecsSinceEpoch() / 1000);
|
||||
});
|
||||
|
||||
connect(monitor, &NetworkDeviceMonitor::networkDeviceInfoChanged, this, [=](const NetworkDeviceInfo &networkInfo){
|
||||
qCDebug(dcNetworkDetector()) << thing << "changed" << networkInfo;
|
||||
thing->setStateValue(networkDeviceAddressStateTypeId, networkInfo.address().toString());
|
||||
thing->setStateValue(networkDeviceHostNameStateTypeId, networkInfo.hostName());
|
||||
thing->setStateValue(networkDeviceMacManufacturerNameStateTypeId, networkInfo.macAddressManufacturer());
|
||||
thing->setStateValue(networkDeviceNetworkInterfaceStateTypeId, monitor->networkDeviceInfo().networkInterface().name());
|
||||
});
|
||||
|
||||
m_monitors.insert(thing, monitor);
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
|
||||
thing->setStateValue(networkDeviceAddressStateTypeId, monitor->networkDeviceInfo().address().toString());
|
||||
thing->setStateValue(networkDeviceHostNameStateTypeId, monitor->networkDeviceInfo().hostName());
|
||||
thing->setStateValue(networkDeviceMacManufacturerNameStateTypeId, monitor->networkDeviceInfo().macAddressManufacturer());
|
||||
thing->setStateValue(networkDeviceNetworkInterfaceStateTypeId, monitor->networkDeviceInfo().networkInterface().name());
|
||||
thing->setStateValue(networkDeviceIsPresentStateTypeId, monitor->reachable());
|
||||
if (!monitor->lastSeen().isNull()) {
|
||||
QDateTime minuteBased = QDateTime::fromMSecsSinceEpoch((monitor->lastSeen().toMSecsSinceEpoch() / 60000) * 60000);
|
||||
thing->setStateValue(networkDeviceLastSeenTimeStateTypeId, minuteBased.toMSecsSinceEpoch() / 1000); }
|
||||
return;
|
||||
QHostAddress cachedAddress;
|
||||
if (!monitor->networkDeviceInfo().address().isNull()) {
|
||||
cachedAddress = monitor->networkDeviceInfo().address();
|
||||
} else {
|
||||
cachedAddress = QHostAddress(thing->stateValue(networkDeviceAddressStateTypeId).toString());
|
||||
}
|
||||
|
||||
// If the address is not known yet, let the monitor do the work and finish the setup...
|
||||
if (cachedAddress.isNull()) {
|
||||
setupMonitorConnections(thing, monitor);
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
thing->setStateValue(networkDeviceIsPresentStateTypeId, monitor->reachable());
|
||||
return;
|
||||
}
|
||||
|
||||
// Make an initial ping in order to check if the device reachable state has changed compaired to the cached state
|
||||
qCDebug(dcNetworkDetector()) << "Send initial ping to" << cachedAddress.toString() << "in order to get initial reachable state...";
|
||||
PingReply *pingReply = hardwareManager()->networkDeviceDiscovery()->ping(cachedAddress);
|
||||
connect(pingReply, &PingReply::finished, this, [=](){
|
||||
|
||||
qCDebug(dcNetworkDetector()) << "Initial ping finished" << pingReply->error();
|
||||
|
||||
// However the ping result is, the monitor has catched up internally with the reachable state...
|
||||
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
|
||||
if (!monitor->networkDeviceInfo().address().isNull())
|
||||
thing->setStateValue(networkDeviceAddressStateTypeId, monitor->networkDeviceInfo().address().toString());
|
||||
|
||||
thing->setStateValue(networkDeviceHostNameStateTypeId, monitor->networkDeviceInfo().hostName());
|
||||
thing->setStateValue(networkDeviceMacManufacturerNameStateTypeId, monitor->networkDeviceInfo().macAddressManufacturer());
|
||||
thing->setStateValue(networkDeviceNetworkInterfaceStateTypeId, monitor->networkDeviceInfo().networkInterface().name());
|
||||
thing->setStateValue(networkDeviceIsPresentStateTypeId, monitor->reachable());
|
||||
|
||||
setupMonitorConnections(thing, monitor);
|
||||
|
||||
if (!monitor->lastSeen().isNull()) {
|
||||
QDateTime minuteBased = QDateTime::fromMSecsSinceEpoch((monitor->lastSeen().toMSecsSinceEpoch() / 60000) * 60000);
|
||||
thing->setStateValue(networkDeviceLastSeenTimeStateTypeId, minuteBased.toMSecsSinceEpoch() / 1000);
|
||||
}
|
||||
|
||||
});
|
||||
} else {
|
||||
info->finish(Thing::ThingErrorThingClassNotFound);
|
||||
}
|
||||
|
||||
info->finish(Thing::ThingErrorThingClassNotFound);
|
||||
}
|
||||
|
||||
void IntegrationPluginNetworkDetector::thingRemoved(Thing *thing)
|
||||
|
|
@ -162,6 +180,10 @@ void IntegrationPluginNetworkDetector::thingRemoved(Thing *thing)
|
|||
if (m_monitors.contains(thing)) {
|
||||
hardwareManager()->networkDeviceDiscovery()->unregisterMonitor(m_monitors.take(thing));
|
||||
}
|
||||
|
||||
if (m_gracePeriodTimers.contains(thing)) {
|
||||
hardwareManager()->pluginTimerManager()->unregisterTimer(m_gracePeriodTimers.take(thing));
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginNetworkDetector::executeAction(ThingActionInfo *info)
|
||||
|
|
@ -205,6 +227,53 @@ void IntegrationPluginNetworkDetector::executeAction(ThingActionInfo *info)
|
|||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginNetworkDetector::setupMonitorConnections(Thing *thing, NetworkDeviceMonitor *monitor)
|
||||
{
|
||||
connect(monitor, &NetworkDeviceMonitor::reachableChanged, thing, [=](bool reachable){
|
||||
qCDebug(dcNetworkDetector()) << thing->name() << "monitor reachable changed to" << reachable;
|
||||
if (reachable) {
|
||||
thing->setStateValue(networkDeviceIsPresentStateTypeId, reachable);
|
||||
// Remove any possible running grace priod timer
|
||||
if (m_gracePeriodTimers.contains(thing)) {
|
||||
hardwareManager()->pluginTimerManager()->unregisterTimer(m_gracePeriodTimers.take(thing));
|
||||
}
|
||||
} else {
|
||||
int gracePeriodSeconds = thing->setting(networkDeviceSettingsGracePeriodParamTypeId).toInt() * 60;
|
||||
if (gracePeriodSeconds == 0) {
|
||||
thing->setStateValue(networkDeviceIsPresentStateTypeId, reachable);
|
||||
} else {
|
||||
// Let's wait the grace period before setting not present
|
||||
PluginTimer *timer = hardwareManager()->pluginTimerManager()->registerTimer(gracePeriodSeconds);
|
||||
connect(timer, &PluginTimer::timeout, thing, [=](){
|
||||
if (thing->stateValue(networkDeviceIsPresentStateTypeId).toBool() && monitor->lastSeen().addSecs(gracePeriodSeconds) < QDateTime::currentDateTime()) {
|
||||
qCDebug(dcNetworkDetector()) << thing->name() << "still not reachable after a grace period of" << gracePeriodSeconds << "seconds. Mark device as not reachable.";
|
||||
thing->setStateValue(networkDeviceIsPresentStateTypeId, reachable);
|
||||
hardwareManager()->pluginTimerManager()->unregisterTimer(m_gracePeriodTimers.take(thing));
|
||||
}
|
||||
});
|
||||
|
||||
m_gracePeriodTimers.insert(thing, timer);
|
||||
qCDebug(dcNetworkDetector()) << "Starting grace period timer" << m_gracePeriodTimers << "seconds";
|
||||
timer->start();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
connect(monitor, &NetworkDeviceMonitor::lastSeenChanged, thing, [=](const QDateTime &lastSeen){
|
||||
QDateTime minuteBased = QDateTime::fromMSecsSinceEpoch((monitor->lastSeen().toMSecsSinceEpoch() / 60000) * 60000);
|
||||
qCDebug(dcNetworkDetector()) << thing << "last seen changed to" << lastSeen.toString() << minuteBased.toString();
|
||||
thing->setStateValue(networkDeviceLastSeenTimeStateTypeId, minuteBased.toMSecsSinceEpoch() / 1000);
|
||||
});
|
||||
|
||||
connect(monitor, &NetworkDeviceMonitor::networkDeviceInfoChanged, thing, [=](const NetworkDeviceInfo &networkInfo){
|
||||
qCDebug(dcNetworkDetector()) << thing << "changed" << networkInfo;
|
||||
thing->setStateValue(networkDeviceAddressStateTypeId, networkInfo.address().toString());
|
||||
thing->setStateValue(networkDeviceHostNameStateTypeId, networkInfo.hostName());
|
||||
thing->setStateValue(networkDeviceMacManufacturerNameStateTypeId, networkInfo.macAddressManufacturer());
|
||||
thing->setStateValue(networkDeviceNetworkInterfaceStateTypeId, monitor->networkDeviceInfo().networkInterface().name());
|
||||
});
|
||||
}
|
||||
|
||||
void IntegrationPluginNetworkDetector::onHostLookupFinished(const QHostInfo &info)
|
||||
{
|
||||
ThingActionInfo *actionInfo = m_pendingHostLookup.take(info.lookupId());
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include <integrations/integrationplugin.h>
|
||||
#include <network/networkdevicediscovery.h>
|
||||
#include <plugintimer.h>
|
||||
|
||||
#include <QHostInfo>
|
||||
|
||||
|
|
@ -56,8 +57,11 @@ public:
|
|||
|
||||
private:
|
||||
QHash<Thing *, NetworkDeviceMonitor *> m_monitors;
|
||||
QHash<Thing *, PluginTimer *> m_gracePeriodTimers;
|
||||
QHash<int, ThingActionInfo *> m_pendingHostLookup;
|
||||
|
||||
void setupMonitorConnections(Thing *thing, NetworkDeviceMonitor *monitor);
|
||||
|
||||
private slots:
|
||||
void onHostLookupFinished(const QHostInfo &info);
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,15 @@
|
|||
"inputType": "MacAddress"
|
||||
}
|
||||
],
|
||||
"settingsTypes": [
|
||||
{
|
||||
"id": "6c1ec0c8-6a02-4b3c-9064-ee33cfd61fbe",
|
||||
"name": "gracePeriod",
|
||||
"displayName": "Grace period (Minutes)",
|
||||
"type": "uint",
|
||||
"defaultValue": 5
|
||||
}
|
||||
],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "acee9260-4d01-471a-85c5-4d6116b35ff1",
|
||||
|
|
@ -30,7 +39,8 @@
|
|||
"displayName": "IP address",
|
||||
"displayNameEvent": "IP address changed",
|
||||
"type": "QString",
|
||||
"defaultValue": "127.0.0.1"
|
||||
"defaultValue": "127.0.0.1",
|
||||
"cached": true
|
||||
},
|
||||
{
|
||||
"id": "29c65dcf-090e-4316-8554-68f038a8416f",
|
||||
|
|
@ -38,7 +48,8 @@
|
|||
"displayName": "Host name",
|
||||
"displayNameEvent": "Host name changed",
|
||||
"type": "QString",
|
||||
"defaultValue": ""
|
||||
"defaultValue": "",
|
||||
"cached": true
|
||||
},
|
||||
{
|
||||
"id": "395623b2-5b25-4582-803e-61cd6d40844c",
|
||||
|
|
@ -46,7 +57,8 @@
|
|||
"displayName": "MAC manufacturer name",
|
||||
"displayNameEvent": "MAC manufacturer name changed",
|
||||
"type": "QString",
|
||||
"defaultValue": ""
|
||||
"defaultValue": "",
|
||||
"cached": true
|
||||
},
|
||||
{
|
||||
"id": "412f0e24-26e7-450b-8e60-bfaf938ea23e",
|
||||
|
|
@ -54,7 +66,8 @@
|
|||
"displayName": "Network interface",
|
||||
"displayNameEvent": "Network interface changed",
|
||||
"type": "QString",
|
||||
"defaultValue": ""
|
||||
"defaultValue": "",
|
||||
"cached": true
|
||||
},
|
||||
{
|
||||
"id": "cb43e1b5-4f61-4538-bfa2-c33055c542cf",
|
||||
|
|
@ -62,7 +75,8 @@
|
|||
"displayName": "Device is present",
|
||||
"displayNameEvent": "Device is present changed",
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
"defaultValue": false,
|
||||
"cached": true
|
||||
},
|
||||
{
|
||||
"id": "b51d54c9-cce1-43f0-a35d-52fc2d8d302c",
|
||||
|
|
@ -71,7 +85,8 @@
|
|||
"displayNameEvent": "Last seen time changed",
|
||||
"type": "int",
|
||||
"unit": "UnixTime",
|
||||
"defaultValue": 0
|
||||
"defaultValue": 0,
|
||||
"cached": true
|
||||
}
|
||||
],
|
||||
"actionTypes": [
|
||||
|
|
|
|||
Loading…
Reference in New Issue