From 60c55f0d852cce26a1ad3ec4522343dbf5d07db4 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Fri, 4 Sep 2020 22:44:21 +0200 Subject: [PATCH] Make signalStrength state in wirelessconnectable optional --- libnymea/interfaces/interfaces.qrc | 2 +- libnymea/interfaces/wirelessconnectable.json | 4 +- plugins/mock/extern-plugininfo.h | 10 ++++ plugins/mock/integrationpluginmock.cpp | 14 +++++ plugins/mock/integrationpluginmock.json | 32 +++++++++-- plugins/mock/plugininfo.h | 58 +++++++++++++++++--- tests/auto/devices/testdevices.cpp | 20 +++---- tests/auto/integrations/testintegrations.cpp | 20 +++---- 8 files changed, 119 insertions(+), 41 deletions(-) diff --git a/libnymea/interfaces/interfaces.qrc b/libnymea/interfaces/interfaces.qrc index 188c79a9..00c41b34 100644 --- a/libnymea/interfaces/interfaces.qrc +++ b/libnymea/interfaces/interfaces.qrc @@ -42,6 +42,7 @@ lightsensor.json thermostat.json connectable.json + wirelessconnectable.json inputtrigger.json outputtrigger.json power.json @@ -74,7 +75,6 @@ windspeedsensor.json co2sensor.json presencesensor.json - wirelessconnectable.json navigationpad.json extendednavigationpad.json closablesensor.json diff --git a/libnymea/interfaces/wirelessconnectable.json b/libnymea/interfaces/wirelessconnectable.json index bd45560d..16bbbe42 100644 --- a/libnymea/interfaces/wirelessconnectable.json +++ b/libnymea/interfaces/wirelessconnectable.json @@ -1,5 +1,5 @@ { - "description": "This interface should be used for device which have the signal strength available. If the signal is to weak, the thing is not connected any more.", + "description": "Interface for wireless connectable devices. If reporting the signal strength is supported, the optional signalStrength state should be implemented.", "extends": "connectable", "states": [ { @@ -8,7 +8,7 @@ "unit": "Percentage", "minValue": 0, "maxValue": 100, - "defaultValue": 0 + "optional": true } ] } diff --git a/plugins/mock/extern-plugininfo.h b/plugins/mock/extern-plugininfo.h index 7887dffb..5e440489 100644 --- a/plugins/mock/extern-plugininfo.h +++ b/plugins/mock/extern-plugininfo.h @@ -26,6 +26,8 @@ extern StateTypeId mockDoubleStateTypeId; extern StateTypeId mockBatteryLevelStateTypeId; extern StateTypeId mockBatteryCriticalStateTypeId; extern StateTypeId mockPowerStateTypeId; +extern StateTypeId mockConnectedStateTypeId; +extern StateTypeId mockSignalStrengthStateTypeId; extern EventTypeId mockIntEventTypeId; extern ParamTypeId mockIntEventIntParamTypeId; extern EventTypeId mockBoolEventTypeId; @@ -38,11 +40,19 @@ extern EventTypeId mockBatteryCriticalEventTypeId; extern ParamTypeId mockBatteryCriticalEventBatteryCriticalParamTypeId; extern EventTypeId mockPowerEventTypeId; extern ParamTypeId mockPowerEventPowerParamTypeId; +extern EventTypeId mockConnectedEventTypeId; +extern ParamTypeId mockConnectedEventConnectedParamTypeId; +extern EventTypeId mockSignalStrengthEventTypeId; +extern ParamTypeId mockSignalStrengthEventSignalStrengthParamTypeId; extern EventTypeId mockEvent1EventTypeId; extern EventTypeId mockEvent2EventTypeId; extern ParamTypeId mockEvent2EventIntParamParamTypeId; +extern ActionTypeId mockBatteryLevelActionTypeId; +extern ParamTypeId mockBatteryLevelActionBatteryLevelParamTypeId; extern ActionTypeId mockPowerActionTypeId; extern ParamTypeId mockPowerActionPowerParamTypeId; +extern ActionTypeId mockSignalStrengthActionTypeId; +extern ParamTypeId mockSignalStrengthActionSignalStrengthParamTypeId; extern ActionTypeId mockWithParamsActionTypeId; extern ParamTypeId mockWithParamsActionParam1ParamTypeId; extern ParamTypeId mockWithParamsActionParam2ParamTypeId; diff --git a/plugins/mock/integrationpluginmock.cpp b/plugins/mock/integrationpluginmock.cpp index ef584c44..a689378d 100644 --- a/plugins/mock/integrationpluginmock.cpp +++ b/plugins/mock/integrationpluginmock.cpp @@ -571,6 +571,20 @@ void IntegrationPluginMock::executeAction(ThingActionInfo *info) qCDebug(dcMock()) << "Setting power to" << info->action().param(mockPowerActionPowerParamTypeId).value().toBool(); info->thing()->setStateValue(mockPowerStateTypeId, info->action().param(mockPowerActionPowerParamTypeId).value().toBool()); } + + if (info->action().actionTypeId() == mockBatteryLevelActionTypeId) { + int newLevel = info->action().param(mockBatteryLevelActionBatteryLevelParamTypeId).value().toInt(); + qCDebug(dcMock()) << "Setting battery level to" << newLevel; + info->thing()->setStateValue(mockBatteryLevelStateTypeId, newLevel); + info->thing()->setStateValue(mockBatteryCriticalStateTypeId, newLevel < 10); + } + + if (info->action().actionTypeId() == mockSignalStrengthActionTypeId) { + int newStrength = info->action().param(mockSignalStrengthActionSignalStrengthParamTypeId).value().toInt(); + qCDebug(dcMock()) << "Setting signal strength to" << newStrength; + info->thing()->setStateValue(mockSignalStrengthStateTypeId, newStrength); + info->thing()->setStateValue(mockConnectedStateTypeId, newStrength != 0); + } m_daemons.value(info->thing())->actionExecuted(info->action().actionTypeId()); info->finish(Thing::ThingErrorNoError); return; diff --git a/plugins/mock/integrationpluginmock.json b/plugins/mock/integrationpluginmock.json index 14953bec..095389d1 100644 --- a/plugins/mock/integrationpluginmock.json +++ b/plugins/mock/integrationpluginmock.json @@ -30,7 +30,7 @@ "id": "753f0d32-0468-4d08-82ed-1964aab03298", "name": "mock", "displayName": "Mock Thing", - "interfaces": ["system", "light", "battery"], + "interfaces": ["system", "light", "batterylevel", "wirelessconnectable"], "createMethods": ["user", "discovery"], "browsable": true, "discoveryParamTypes": [ @@ -106,12 +106,14 @@ { "id": "6c8ab9a6-0164-4795-b829-f4394fe4edc4", "name": "batteryLevel", - "displayName": "battery level", - "displayNameEvent": "battery level", + "displayName": "Battery level", + "displayNameEvent": "Battery level", + "displayNameAction": "Set battery level", "type": "int", "minValue": 0, "maxValue": 100, - "defaultValue": 0 + "defaultValue": 0, + "writable": true }, { "id": "580bc611-1a55-41f3-996f-8d3ccf543db3", @@ -130,8 +132,28 @@ "type": "bool", "defaultValue": false, "writable": true + }, + { + "id": "9860d105-2bd9-4651-9bc9-13ff4b9039a7", + "name": "connected", + "displayName": "Connected", + "displayNameEvent": "Connected changed", + "type": "bool", + "defaultValue": true + }, + { + "id": "2a0213bf-4af3-4384-904e-3376348a597e", + "name": "signalStrength", + "displayName": "Signal strength", + "displayNameEvent": "Signal strength changed", + "displayNameAction": "Set signal strength", + "type": "uint", + "unit": "Percentage", + "minValue": 0, + "maxValue": 100, + "defaultValue": 50, + "writable": true } - ], "eventTypes": [ { diff --git a/plugins/mock/plugininfo.h b/plugins/mock/plugininfo.h index 4e4b891a..002d9b16 100644 --- a/plugins/mock/plugininfo.h +++ b/plugins/mock/plugininfo.h @@ -30,6 +30,8 @@ StateTypeId mockDoubleStateTypeId = StateTypeId("{7cac53ee-7048-4dc9-b000-7b5853 StateTypeId mockBatteryLevelStateTypeId = StateTypeId("{6c8ab9a6-0164-4795-b829-f4394fe4edc4}"); StateTypeId mockBatteryCriticalStateTypeId = StateTypeId("{580bc611-1a55-41f3-996f-8d3ccf543db3}"); StateTypeId mockPowerStateTypeId = StateTypeId("{064aed0d-da4c-49d4-b236-60f97e98ff84}"); +StateTypeId mockConnectedStateTypeId = StateTypeId("{9860d105-2bd9-4651-9bc9-13ff4b9039a7}"); +StateTypeId mockSignalStrengthStateTypeId = StateTypeId("{2a0213bf-4af3-4384-904e-3376348a597e}"); EventTypeId mockIntEventTypeId = EventTypeId("{80baec19-54de-4948-ac46-31eabfaceb83}"); ParamTypeId mockIntEventIntParamTypeId = ParamTypeId("{80baec19-54de-4948-ac46-31eabfaceb83}"); EventTypeId mockBoolEventTypeId = EventTypeId("{9dd6a97c-dfd1-43dc-acbd-367932742310}"); @@ -42,11 +44,19 @@ EventTypeId mockBatteryCriticalEventTypeId = EventTypeId("{580bc611-1a55-41f3-99 ParamTypeId mockBatteryCriticalEventBatteryCriticalParamTypeId = ParamTypeId("{580bc611-1a55-41f3-996f-8d3ccf543db3}"); EventTypeId mockPowerEventTypeId = EventTypeId("{064aed0d-da4c-49d4-b236-60f97e98ff84}"); ParamTypeId mockPowerEventPowerParamTypeId = ParamTypeId("{064aed0d-da4c-49d4-b236-60f97e98ff84}"); +EventTypeId mockConnectedEventTypeId = EventTypeId("{9860d105-2bd9-4651-9bc9-13ff4b9039a7}"); +ParamTypeId mockConnectedEventConnectedParamTypeId = ParamTypeId("{9860d105-2bd9-4651-9bc9-13ff4b9039a7}"); +EventTypeId mockSignalStrengthEventTypeId = EventTypeId("{2a0213bf-4af3-4384-904e-3376348a597e}"); +ParamTypeId mockSignalStrengthEventSignalStrengthParamTypeId = ParamTypeId("{2a0213bf-4af3-4384-904e-3376348a597e}"); EventTypeId mockEvent1EventTypeId = EventTypeId("{45bf3752-0fc6-46b9-89fd-ffd878b5b22b}"); EventTypeId mockEvent2EventTypeId = EventTypeId("{863d5920-b1cf-4eb9-88bd-8f7b8583b1cf}"); ParamTypeId mockEvent2EventIntParamParamTypeId = ParamTypeId("{0550e16d-60b9-4ba5-83f4-4d3cee656121}"); +ActionTypeId mockBatteryLevelActionTypeId = ActionTypeId("{6c8ab9a6-0164-4795-b829-f4394fe4edc4}"); +ParamTypeId mockBatteryLevelActionBatteryLevelParamTypeId = ParamTypeId("{6c8ab9a6-0164-4795-b829-f4394fe4edc4}"); ActionTypeId mockPowerActionTypeId = ActionTypeId("{064aed0d-da4c-49d4-b236-60f97e98ff84}"); ParamTypeId mockPowerActionPowerParamTypeId = ParamTypeId("{064aed0d-da4c-49d4-b236-60f97e98ff84}"); +ActionTypeId mockSignalStrengthActionTypeId = ActionTypeId("{2a0213bf-4af3-4384-904e-3376348a597e}"); +ParamTypeId mockSignalStrengthActionSignalStrengthParamTypeId = ParamTypeId("{2a0213bf-4af3-4384-904e-3376348a597e}"); ActionTypeId mockWithParamsActionTypeId = ActionTypeId("{dea0f4e1-65e3-4981-8eaa-2701c53a9185}"); ParamTypeId mockWithParamsActionParam1ParamTypeId = ParamTypeId("{a2d3a256-a551-4712-a65b-ecd5a436a1cb}"); ParamTypeId mockWithParamsActionParam2ParamTypeId = ParamTypeId("{304a4899-18be-4e3b-94f4-d03be52f3233}"); @@ -353,6 +363,18 @@ const QString translations[] { //: The name of the EventType ({e40bcf7d-47b8-41fa-b213-3652a905b376}) of ThingClass genericIoMock QT_TRANSLATE_NOOP("mock", "Analog Output 2 changed"), + //: The name of the ParamType (ThingClass: mock, ActionType: batteryLevel, ID: {6c8ab9a6-0164-4795-b829-f4394fe4edc4}) + QT_TRANSLATE_NOOP("mock", "Battery level"), + + //: The name of the ParamType (ThingClass: mock, EventType: batteryLevel, ID: {6c8ab9a6-0164-4795-b829-f4394fe4edc4}) + QT_TRANSLATE_NOOP("mock", "Battery level"), + + //: The name of the EventType ({6c8ab9a6-0164-4795-b829-f4394fe4edc4}) of ThingClass mock + QT_TRANSLATE_NOOP("mock", "Battery level"), + + //: The name of the StateType ({6c8ab9a6-0164-4795-b829-f4394fe4edc4}) of ThingClass mock + QT_TRANSLATE_NOOP("mock", "Battery level"), + //: The name of the ParamType (ThingClass: inputTypeMock, EventType: bool, ID: {3bad3a09-5826-4ed7-a832-10e3e2ee2a7d}) QT_TRANSLATE_NOOP("mock", "Bool"), @@ -371,6 +393,15 @@ const QString translations[] { //: The name of the EventType ({4507d5c6-b692-4bd6-87f2-00364bc0cb4d}) of ThingClass inputTypeMock QT_TRANSLATE_NOOP("mock", "Color changed"), + //: The name of the ParamType (ThingClass: mock, EventType: connected, ID: {9860d105-2bd9-4651-9bc9-13ff4b9039a7}) + QT_TRANSLATE_NOOP("mock", "Connected"), + + //: The name of the StateType ({9860d105-2bd9-4651-9bc9-13ff4b9039a7}) of ThingClass mock + QT_TRANSLATE_NOOP("mock", "Connected"), + + //: The name of the EventType ({9860d105-2bd9-4651-9bc9-13ff4b9039a7}) of ThingClass mock + QT_TRANSLATE_NOOP("mock", "Connected changed"), + //: The name of the ParamType (ThingClass: genericIoMock, ActionType: digitalOutput1, ID: {d6fcdb52-f7c3-423b-b9f5-1e29f164c42e}) QT_TRANSLATE_NOOP("mock", "Digital Output 1"), @@ -674,6 +705,9 @@ const QString translations[] { //: The name of the ActionType ({ac56977c-cbba-47c6-a827-5735d8b0aed6}) of ThingClass genericIoMock QT_TRANSLATE_NOOP("mock", "Set analog input 1"), + //: The name of the ActionType ({6c8ab9a6-0164-4795-b829-f4394fe4edc4}) of ThingClass mock + QT_TRANSLATE_NOOP("mock", "Set battery level"), + //: The name of the ActionType ({80ba1449-b485-47d4-a067-6bf306e2a568}) of ThingClass childMock QT_TRANSLATE_NOOP("mock", "Set bool value"), @@ -710,9 +744,24 @@ const QString translations[] { //: The name of the ActionType ({d1917b3d-1530-4cf9-90f7-263ee88e714b}) of ThingClass virtualIoLightMock QT_TRANSLATE_NOOP("mock", "Set power"), + //: The name of the ActionType ({2a0213bf-4af3-4384-904e-3376348a597e}) of ThingClass mock + QT_TRANSLATE_NOOP("mock", "Set signal strength"), + //: The name of the ParamType (ThingClass: mock, Type: settings, ID: {367f7ba4-5039-47be-abd8-59cc8eaf4b9a}) QT_TRANSLATE_NOOP("mock", "Setting 1"), + //: The name of the ParamType (ThingClass: mock, ActionType: signalStrength, ID: {2a0213bf-4af3-4384-904e-3376348a597e}) + QT_TRANSLATE_NOOP("mock", "Signal strength"), + + //: The name of the ParamType (ThingClass: mock, EventType: signalStrength, ID: {2a0213bf-4af3-4384-904e-3376348a597e}) + QT_TRANSLATE_NOOP("mock", "Signal strength"), + + //: The name of the StateType ({2a0213bf-4af3-4384-904e-3376348a597e}) of ThingClass mock + QT_TRANSLATE_NOOP("mock", "Signal strength"), + + //: The name of the EventType ({2a0213bf-4af3-4384-904e-3376348a597e}) of ThingClass mock + QT_TRANSLATE_NOOP("mock", "Signal strength changed"), + //: The name of the ParamType (ThingClass: inputTypeMock, EventType: string, ID: {27f69ca9-a321-40ff-bfee-4b0272a671b4}) QT_TRANSLATE_NOOP("mock", "String"), @@ -968,15 +1017,6 @@ const QString translations[] { //: The name of the ParamType (ThingClass: mock, Type: thing, ID: {f2977061-4dd0-4ef5-85aa-3b7134743be3}) QT_TRANSLATE_NOOP("mock", "async"), - //: The name of the ParamType (ThingClass: mock, EventType: batteryLevel, ID: {6c8ab9a6-0164-4795-b829-f4394fe4edc4}) - QT_TRANSLATE_NOOP("mock", "battery level"), - - //: The name of the EventType ({6c8ab9a6-0164-4795-b829-f4394fe4edc4}) of ThingClass mock - QT_TRANSLATE_NOOP("mock", "battery level"), - - //: The name of the StateType ({6c8ab9a6-0164-4795-b829-f4394fe4edc4}) of ThingClass mock - QT_TRANSLATE_NOOP("mock", "battery level"), - //: The name of the ParamType (ThingClass: mock, EventType: batteryCritical, ID: {580bc611-1a55-41f3-996f-8d3ccf543db3}) QT_TRANSLATE_NOOP("mock", "battery level critical"), diff --git a/tests/auto/devices/testdevices.cpp b/tests/auto/devices/testdevices.cpp index bc2f5d4c..d4557eb9 100644 --- a/tests/auto/devices/testdevices.cpp +++ b/tests/auto/devices/testdevices.cpp @@ -327,14 +327,10 @@ void TestDevices::verifyInterfaces() QVERIFY(!mockDevice.isEmpty()); QVariantList interfaces = mockDevice.value("interfaces").toList(); - // Must contain system, power, light and battery, but must not contain gateway as the device manager should filter - // that away because it doesn't implement all the required states. - QCOMPARE(interfaces.count(), 4); - QVERIFY(interfaces.contains("system")); - QVERIFY(interfaces.contains("battery")); - QVERIFY(interfaces.contains("power")); - QVERIFY(interfaces.contains("light")); - QVERIFY(!interfaces.contains("gateway")); + QVariantList expectedInterfaces = {"system", "light", "power", "batterylevel", "battery", "wirelesssignalstrength", "wirelessconnectable", "connectable"}; + qCDebug(dcTests()) << interfaces; + qCDebug(dcTests()) << expectedInterfaces; + QCOMPARE(interfaces, expectedInterfaces); } void TestDevices::addConfiguredDevice_data() @@ -900,7 +896,7 @@ void TestDevices::getActionTypes_data() QTest::addColumn >("actionTypeTestData"); QTest::newRow("valid deviceclass") << mockThingClassId - << (QList() << mockAsyncActionTypeId << mockAsyncFailingActionTypeId << mockFailingActionTypeId << mockWithoutParamsActionTypeId << mockPowerActionTypeId << mockWithoutParamsActionTypeId); + << (QList() << mockAsyncActionTypeId << mockAsyncFailingActionTypeId << mockFailingActionTypeId << mockWithoutParamsActionTypeId << mockPowerActionTypeId << mockWithoutParamsActionTypeId << mockBatteryLevelActionTypeId << mockSignalStrengthActionTypeId); QTest::newRow("invalid deviceclass") << ThingClassId("094f8024-5caa-48c1-ab6a-de486a92088f") << QList(); } @@ -932,7 +928,7 @@ void TestDevices::getEventTypes_data() QTest::addColumn("deviceClassId"); QTest::addColumn("resultCount"); - QTest::newRow("valid deviceclass") << mockThingClassId << 8; + QTest::newRow("valid deviceclass") << mockThingClassId << 10; QTest::newRow("invalid deviceclass") << ThingClassId("094f8024-5caa-48c1-ab6a-de486a92088f") << 0; } @@ -957,7 +953,7 @@ void TestDevices::getStateTypes_data() QTest::addColumn("thingClassId"); QTest::addColumn("resultCount"); - QTest::newRow("valid deviceclass") << mockThingClassId << 6; + QTest::newRow("valid deviceclass") << mockThingClassId << 8; QTest::newRow("invalid deviceclass") << ThingClassId("094f8024-5caa-48c1-ab6a-de486a92088f") << 0; } @@ -1056,7 +1052,7 @@ void TestDevices::getStateValues() QCOMPARE(response.toMap().value("params").toMap().value("deviceError").toString(), enumValueName(statusCode)); if (statusCode == Device::DeviceErrorNoError) { QVariantList values = response.toMap().value("params").toMap().value("values").toList(); - QCOMPARE(values.count(), 6); // Mock device has 6 states... + QCOMPARE(values.count(), 8); // Mock device has 8 states... } } diff --git a/tests/auto/integrations/testintegrations.cpp b/tests/auto/integrations/testintegrations.cpp index b3c6e373..d18077af 100644 --- a/tests/auto/integrations/testintegrations.cpp +++ b/tests/auto/integrations/testintegrations.cpp @@ -327,14 +327,10 @@ void TestIntegrations::verifyInterfaces() QVERIFY(!mock.isEmpty()); QVariantList interfaces = mock.value("interfaces").toList(); - // Must contain system, power, light and battery, but must not contain gateway as the thing manager should filter - // that away because it doesn't implement all the required states. - QCOMPARE(interfaces.count(), 4); - QVERIFY(interfaces.contains("system")); - QVERIFY(interfaces.contains("battery")); - QVERIFY(interfaces.contains("power")); - QVERIFY(interfaces.contains("light")); - QVERIFY(!interfaces.contains("gateway")); + QVariantList expectedInterfaces = {"system", "light", "power", "batterylevel", "battery", "wirelesssignalstrength", "wirelessconnectable", "connectable"}; + qCDebug(dcTests()) << interfaces; + qCDebug(dcTests()) << expectedInterfaces; + QCOMPARE(interfaces, expectedInterfaces); } void TestIntegrations::addThing_data() @@ -898,7 +894,7 @@ void TestIntegrations::getActionTypes_data() QTest::addColumn >("actionTypeTestData"); QTest::newRow("valid thingClass") << mockThingClassId - << (QList() << mockAsyncActionTypeId << mockAsyncFailingActionTypeId << mockFailingActionTypeId << mockWithoutParamsActionTypeId << mockPowerActionTypeId << mockWithoutParamsActionTypeId); + << (QList() << mockAsyncActionTypeId << mockAsyncFailingActionTypeId << mockFailingActionTypeId << mockWithoutParamsActionTypeId << mockPowerActionTypeId << mockWithoutParamsActionTypeId << mockBatteryLevelActionTypeId << mockSignalStrengthActionTypeId); QTest::newRow("invalid thingClass") << ThingClassId("094f8024-5caa-48c1-ab6a-de486a92088f") << QList(); } @@ -930,7 +926,7 @@ void TestIntegrations::getEventTypes_data() QTest::addColumn("thingClassId"); QTest::addColumn("resultCount"); - QTest::newRow("valid thingClass") << mockThingClassId << 8; + QTest::newRow("valid thingClass") << mockThingClassId << 10; QTest::newRow("invalid thingClass") << ThingClassId("094f8024-5caa-48c1-ab6a-de486a92088f") << 0; } @@ -955,7 +951,7 @@ void TestIntegrations::getStateTypes_data() QTest::addColumn("thingClassId"); QTest::addColumn("resultCount"); - QTest::newRow("valid thingClass") << mockThingClassId << 6; + QTest::newRow("valid thingClass") << mockThingClassId << 8; QTest::newRow("invalid thingClass") << ThingClassId("094f8024-5caa-48c1-ab6a-de486a92088f") << 0; } @@ -1025,7 +1021,7 @@ void TestIntegrations::getStateValues() QCOMPARE(response.toMap().value("params").toMap().value("thingError").toString(), enumValueName(statusCode)); if (statusCode == Thing::ThingErrorNoError) { QVariantList values = response.toMap().value("params").toMap().value("values").toList(); - QCOMPARE(values.count(), 6); // Mock has 6 states... + QCOMPARE(values.count(), 8); // Mock has 8 states... } }