diff --git a/libnymea-app/types/interfaces.cpp b/libnymea-app/types/interfaces.cpp index b2b35fa9..96910a36 100644 --- a/libnymea-app/types/interfaces.cpp +++ b/libnymea-app/types/interfaces.cpp @@ -89,7 +89,11 @@ Interfaces::Interfaces(QObject *parent) : QAbstractListModel(parent) addInterface("sensor", tr("Sensors")); addInterface("cleaningrobot", tr("Cleaning robots")); - addStateType("cleaningrobot", "state", QVariant::String, false, tr("Cleaning state"), tr("Cleaning state changed")); + addStateType("cleaningrobot", "robotState", QVariant::String, false, tr("Robot state"), tr("Robot state changed")); + addActionType("cleaningrobot", "startCleaning", tr("Start cleaning"), new ParamTypes()); + addActionType("cleaningrobot", "stopCleaning", tr("Stop cleaning"), new ParamTypes()); + addActionType("cleaningrobot", "pauseCleaning", tr("Pause cleaning"), new ParamTypes()); + addActionType("cleaningrobot", "returnToBase", tr("Return to base"), new ParamTypes()); addInterface("closablesensor", tr("Closable sensors"), {"sensor"}); addStateType("closablesensor", "closed", QVariant::Bool, false, tr("Closed"), tr("Opened or closed")); diff --git a/nymea-app/ui/Nymea.qml b/nymea-app/ui/Nymea.qml index 3f4c0ba7..9dec10a3 100644 --- a/nymea-app/ui/Nymea.qml +++ b/nymea-app/ui/Nymea.qml @@ -238,6 +238,8 @@ ApplicationWindow { return qsTr("Ventilation") case "barcodescanner": return qsTr("Barcode scanners"); + case "cleaningrobot": + return qsTr("Cleaning robots") case "uncategorized": return qsTr("Uncategorized") default: diff --git a/nymea-app/ui/delegates/InterfaceTile.qml b/nymea-app/ui/delegates/InterfaceTile.qml index 980531a9..b68f8238 100644 --- a/nymea-app/ui/delegates/InterfaceTile.qml +++ b/nymea-app/ui/delegates/InterfaceTile.qml @@ -190,6 +190,7 @@ MainPageTile { case "powersocket": case "irrigation": case "ventilation": + case "cleaningrobot": return buttonComponent case "media": return mediaControlComponent @@ -271,7 +272,10 @@ MainPageTile { Layout.fillWidth: true spacing: 0 - Item { Layout.fillWidth: true; Layout.fillHeight: true } + Item { + Layout.fillWidth: true; Layout.fillHeight: true + visible: label.visible || firstButton.visible + } Label { id: label @@ -310,6 +314,7 @@ MainPageTile { } ProgressButton { + id: firstButton longpressEnabled: false visible: imageSource.length > 0 color: Style.tileOverlayIconColor @@ -336,6 +341,10 @@ MainPageTile { case "shutter": case "extendedshutter": return "../images/up.svg" + case "cleaningrobot": + var thing = thingsProxy.get(0) + var robotState = thing.stateByName("robotState") + return robotState.value == "cleaning" ? "../images/media-playback-pause.svg" : "../images/media-playback-start.svg" default: console.warn("InterfaceTile", "inlineButtonControl image: Unhandled interface", iface.name) } @@ -375,15 +384,28 @@ MainPageTile { engine.thingManager.executeAction(device.id, actionType.id) } break; + case "cleaningrobot": + var thing = thingsProxy.get(0) + var robotState = thing.stateByName("robotState") + if (robotState.value === "cleaning" || robotState.value === "paused") { + engine.thingManager.executeAction(thing.id, thing.thingClass.actionTypes.findByName("pauseCleaning").id) + } else { + engine.thingManager.executeAction(thing.id, thing.thingClass.actionTypes.findByName("startCleaning").id) + } + break; default: console.warn("InterfaceTile:", "inlineButtonControl clicked: Unhandled interface", iface.name) } } } - Item { Layout.fillWidth: true; Layout.fillHeight: true } + Item { + Layout.fillWidth: true; Layout.fillHeight: true + visible: secondButton.visible + } ProgressButton { + id: secondButton longpressEnabled: false visible: imageSource.length > 0 color: Style.tileOverlayIconColor @@ -409,6 +431,7 @@ MainPageTile { case "extendedblind": case "extendedawning": case "extendedshutter": + case "cleaningrobot": return "../images/media-playback-stop.svg" default: console.warn("InterfaceTile, inlineButtonControl image: Unhandled interface", iface.name) @@ -449,15 +472,24 @@ MainPageTile { engine.thingManager.executeAction(device.id, actionType.id) } break; + case "cleaningrobot": + var thing = thingsProxy.get(0) + engine.thingManager.executeAction(thing.id, thing.thingClass.actionTypes.findByName("stopCleaning").id) + break; default: console.warn("InterfaceTile, inlineButtonControl clicked: Unhandled interface", iface.name) } } } - Item { Layout.fillWidth: true; Layout.fillHeight: true } + Item { + Layout.fillWidth: true; Layout.fillHeight: true + visible: thirdButton.visible + } ProgressButton { + id: thirdButton longpressEnabled: false + visible: imageSource.length > 0 color: Style.tileOverlayIconColor imageSource: { switch (iface.name) { @@ -571,6 +603,8 @@ MainPageTile { var actionType = thing.thingClass.actionTypes.findByName("close"); engine.thingManager.executeAction(thing.id, actionType.id) } + case "cleaningrobot": + default: console.warn("InterfaceTile, inlineButtonControl clicked: Unhandled interface", iface.name) diff --git a/nymea-app/ui/devicepages/CleaningRobotThingPage.qml b/nymea-app/ui/devicepages/CleaningRobotThingPage.qml index 6b522734..aa399005 100644 --- a/nymea-app/ui/devicepages/CleaningRobotThingPage.qml +++ b/nymea-app/ui/devicepages/CleaningRobotThingPage.qml @@ -70,6 +70,7 @@ ThingPageBase { Timer { interval: 500 running: true + repeat: false onTriggered: { robotArea.initialized = true; robot.evaluateState() @@ -115,7 +116,7 @@ ThingPageBase { } return case "docked": - if (robotArea.robotX != robotArea.radius || robotArea.robotY != robotArea.radius) { + if (Math.abs(robotArea.robotX - robotArea.radius) > 2 || Math.abs(robotArea.robotY - robotArea.radius) > 2 || robot.rotation != 0) { robot.travel(true) } return @@ -133,6 +134,7 @@ ThingPageBase { } function travel(toHome) { + print("robot traveling") var areaWidth = robotArea.width; var radius = areaWidth / 2 @@ -159,7 +161,7 @@ ThingPageBase { var toXCentered = toX - centerX var toYCentered = toY - centerY distanceToCenter = Math.abs(Math.sqrt(Math.pow(toXCentered, 2) + Math.pow(toYCentered, 2))) - print("new pos:", toX, toY, "to center:", toXCentered, toYCentered, "radius:", radius, "distance to center", distanceToCenter) +// print("new pos:", toX, toY, "to center:", toXCentered, toYCentered, "radius:", radius, "distance to center", distanceToCenter) } while (distanceToCenter > (radius - robot.width / 2)) } @@ -176,8 +178,11 @@ ThingPageBase { travelYAnimation.duration = travelDuration rotationAnimation.from = robot.rotation - rotationAnimation.to = robot.getAngleDegrees(fromX, fromY, toX, toY) - print(":", fromX, fromY, toX, toY, rotationAnimation.to, "__", robotArea.robotX) + if (Math.abs(fromX - toX) <= 1 && Math.abs(fromY - toY) <= 1) { + rotationAnimation.to = 0; + } else { + rotationAnimation.to = robot.getAngleDegrees(fromX, fromY, toX, toY) + } travelAnimation.start() }