I do not believe the API gives you access to the “cleaned areas.” I have only been able to find this in the SmartThings app. Samsung has a site that lists the Capabilities for all of their devices, including the POWERbot R7070, so you could double-check there in case I missed something.
You’ll need a SmartThings API Personal Token.
Basically, what I ended up doing is first creating a script that POST
s to the SmartThings API whenever a command changes. From what I can remember, the HTTP binding in openHAB do not let you set HTTP headers with a POST
request (which I needed to pass the authorization token), and the HTTP util functions don’t allow it either, so I had to write this script for it:
import org.eclipse.xtext.xbase.lib.Functions
import java.net.URL
import java.nio.charset.StandardCharsets
import javax.net.ssl.HttpsURLConnection
import java.io.BufferedInputStream
import java.io.BufferedReader
import java.io.InputStreamReader
// Function called to send command to Samsung SmartThings API. This was required
// because the HTTP binding does not allow us to POST with headers.
//
// Inspiration: https://community.openhab.org/t/icloud-device-data-integration-in-openhab/32329
val Functions$Function3<String, String, String, String> sendVacuumCommand= [ capability, command, argument |
val String filename = "robotvacuum.rules"
var String jsonResponse = null
logInfo(filename, "Sending command to Samsung Robot Vacuum.")
try {
var commandUrl = new URL("https://api.smartthings.com/v1/devices/[device ID here]/commands");
var HttpsURLConnection connection = commandUrl.openConnection() as HttpsURLConnection
var request = '{"commands": [{"capability": "%1$s", "command": "%2$s", "arguments": ["%3$s"] }]}'.format(capability, command, argument)
var byte[] postData = request.getBytes(StandardCharsets.UTF_8)
connection.requestMethod = "POST"
connection.setRequestProperty("Accept", "*/*")
connection.setRequestProperty("Authorization", "Bearer [API key here]")
connection.setRequestProperty("Content-Type", "application/json; charset=utf-8")
connection.doOutput = true
connection.setDoInput = true
connection.outputStream.write(postData)
var responseCode = connection.responseCode
logInfo(filename, "Got HTTP response code:" + responseCode)
logInfo(filename, "Got message: " + connection.responseMessage)
var StringBuffer sb = new StringBuffer()
var inputStream = new BufferedInputStream(connection.getInputStream())
var BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))
var String inputLine = ""
while ((inputLine = br.readLine()) !== null) {
sb.append(inputLine)
}
jsonResponse = sb.toString()
inputStream.close()
br.close()
connection.disconnect()
} catch (Exception e) {
logError(filename, "Error sending command to Samsung Robot Vacuum: " + e.toString)
}
return jsonResponse
]
So far, I am using this script to send 3 commands:
sendVacuumCommand.apply("robotCleanerMovement", "setRobotCleanerMovement", [oneof: "cleaning", "homing", "charging"])
sendVacuumCommand.apply("robotCleanerCleaningMode", "setRobotCleanerCleaningMode", [oneof: "auto", "repeat", "stop"])
sendVacuumCommand.apply("robotCleanerTurboMode", "setRobotCleanerTurboMode", [oneof: "on", "off", "silence"])
To activate the vacuum, I use
// Order matters here, at least it did for my experimentation.
sendVacuumCommand.apply("robotCleanerCleaningMode", "setRobotCleanerCleaningMode", "auto")
sendVacuumCommand.apply("robotCleanerMovement", "setRobotCleanerMovement", "cleaning")
To deactivate it, I use,
sendVacuumCommand.apply("robotCleanerMovement", "setRobotCleanerMovement", "homing")
And finally, to retrieve the status of the vacuum, I can actually use the HTTP binding since GET
requests allow headers. Define the item:
String RobotVacuumStatusJson " Robot Vacuum Status" { http="<[https://api.smartthings.com/v1/devices/[device ID here]/status{Authorization=Bearer [API key here]&Content-Type=application/json; charset=utf-8}:60000:REGEX((.*))]" }
This JSON needs to be parsed out to get the status of each individual capability. Whenever that JSON gets updated, I run the following in a rule:
RobotVacuumBatteryLevel.postUpdate(transform("JSONPATH", "components.main.battery[*].value", RobotVacuumStatusJson.state.toString))
RobotVacuumCleanerMovement.postUpdate(transform("JSONPATH", "components.main.robotCleanerMovement[*].value", RobotVacuumStatusJson.state.toString))
RobotVacuumCleaningMode.postUpdate(transform("JSONPATH", "components.main.robotCleanerCleaningMode[*].value", RobotVacuumStatusJson.state.toString))
RobotVacuumCleanerSuctionMode.postUpdate(transform("JSONPATH", "components.main.robotCleanerTurboMode[*].value", RobotVacuumStatusJson.state.toString))
Hope you can get this working
If you do manage to get a map or extend/improve this implementation, please let me know! I would be very interested.