Is imageCapture capability not supported anymore?

What is the SmartThings current official position on imageCapture capability ?

I want to capture an image from my SmartApp and I have used 2 cameras from the list of compatible devices: https://www.smartthings.com/compatible-products
but both cameras don’t support the imageCapture capability.

So is imageCapture capability no longer supported ?

it still exists but is not supported officially. There are lots of cameras that have custom DTH that support imageCapture:

Just be aware that SmartThings won’t tell us where those images get stored, how we can see what’s been stored, or what happens to them once the device and/or SmartApp get removed.

I’ve asked those questions multiple times over the last 2 months, but they still haven’t answered them. I hope I’m wrong, but I have a feeling that they haven’t answered because they don’t want to admit that once a photo is taken, there’s no way to delete it.

@blebson Yes, I saw your post (Great work by the way :thumbsup: ), but I don’t want to use the custom DTHs.

I am currently developing a Web Service SmartApp and taking images from authorized cameras is part of its functionality. I cannot expect the end-users to add a custom DTH for their cameras so the SmartApp can take pictures.

So that’s why I was asking about the support of the imageCapture capability. If its not supported then is there any other way to take pictures from devices ?

The officially compatible cameras support videoCapture and videoCamera/videoPlayer capabilities, but I didn’t find any official documentation regarding these capabilities, so I cannot implement even that.

@krlaframboise These images are stored in the S3 cloud. I experimented with this custom device:

and using the SmartThings storeImage API (also deprecated and no longer officially supported) and you can access your image at: https://graph.api.smartthings.com/api/s3/smartthings-smartsense-camera/[imageFileName]. But the disturbing thing I found was that I have multiple SmartThings accounts and when I am logged-in to any one of them, I can view the images taken from the SmartApps that were installed to the other accounts.

Regarding how to remove those images and what happens to them after the SmartApp was removed, I have no idea at the moment.

I knew they were accessible from that smartsense camera url, but I had no way of testing whether or not they were secure.

Thank you for confirming that they’re not secure

@blebson So I tried to implement the imageCapture capability in my app for a demo by using your DTH for DCS-5222L. It worked great. However, I have a couple of questions:

1- You are storing the images in S3 cloud using the storeImage API, but I want to store these images somewhere else, so how can I get the captured image contents in the parse() method if I remove the hubAction.options=[outputMsgToS3:true] line from the take() method ?

2- In the putImageInS3() method, you first obtain the image from the S3 bucket and then stored it again in S3 using storeImage API. Is the image in the map.bucket stored temporarily or do we now have 2 copies of the image in the S3 cloud ?

Honestly I’m not sure how it all works, though I believe you won’t be able to store the images outside of the cloud. @pstuart is the image capture guru (my image capture code is directly copied from him).

I’m not sure if this helps, but if you encode the image bytes to base64, you can save it anywhere you want as a string and then display it using:

<img src="data:image/jpeg;base64,...

Yes, that’s exactly how I did it to store the image outside of S3. However, my problem here is how to get the image bytes if I remove the S3 part completely. Currently, I am still dependent on S3 bucket to get the image bytes.

Which DTH or SmartApp is the image related code in and around what line number?

This is the link of DTH I am using

Please see the take() method at line 280.

if you set the option outputMsgToS3 to false on line 310, does it make line 196 execute instead of line 193?

If not, have you tried commenting out line 515 and encoding it to base64 instead? Multiple variables are named bytes in that method, but I’m not sure if any of them are an actual byte array. If that’s the section you’re having trouble encoding to base 64, try replacing line 515 with something like:

//storeImage(getPictureName(), bytes)
def encodedImage
def actualBytes = bytes?.buf
if(actualBytes) {
    encodedImage = actualBytes.encodeBase64()
}

No, line 196 does not execute upon setting option outputMsgToS3 to false. Here’s the output of line 182 when I set the outputMsgToS3 to false

Parsing index:17, mac:B0C5540DE996, ip:0A000135,
port:0050, requestId:9578e596-e27d-4578-9767-6ad1bf208235,
headers:SFRUUC8xLjEgMjAwIE9LDQpDb250ZW50LVR5cGU6IGltYWdlL2pwZWcNClByYWdtYTogbm8tY2FjaGUNCkNhY2hlLUNvbnRyb2w6IG5vLXN0b3JlDQpDb250ZW50LUxlbmd0aDogMzczMzE=

And here’s the output of line 187 (parseLanMessage(description)):

msg: [index:17, mac:B0C5540DE996, ip:0A000135, port:0050, requestId:9578e596-e27d-4578-9767-6ad1bf208235,
headers:[content-length:37331, http/1.1 200 ok:null, cache-control:no-store, pragma:no-cache, contenttype:image/jpeg], header:HTTP/1.1 200 OK
Content-Type: image/jpeg
Pragma: no-cache
Cache-Control: no-store
Content-Length: 37331, status:200]

So, as you can see, I got the details of the request headers etc. but I don’t get the byte stream.
Also, the condition at line 200 “if (msg.body)” resolves to false.

Have you tried making the changes I suggested to line 515?

All you’re trying to do is save the data, so let the method putImageInS3 handle getting the byte stream for you and comment out the line that actually stores the image. Once you have that stream, you can encode it and save it somewhere else.

I don’t have any issues once I got the bytes from line 514 to encode them and store it outside of the cloud and commenting out 515 as I mentioned in the post # 11. My issue here is line 510 which indicates that the image is initially stored in an S3 bucket and its the only source so far to get the image bytes in line 514. This is the part that I want to avoid unless the image is temporarily stored in the bucket .

Please see my 2nd question in the post # 9.

Sorry, I didn’t notice that APi call and I thought it was stored in a regular map with bucket as the key.

This is just a random guess, but after setting outputMsgToS3 to false, have you checked to see if descMap.data?.count returns anything?

descMap.data?.count is null

I figured it wouldn’t work, but it works with my remote camera so I thought I’d mention it. Sorry, I can’t think of anything else to try.

The reason local hubaction doesn’t have access to the raw stream is the hub truncates the size of the response. The S3 action was meant to be a way to relay larger packets to AWS S3 to make it then available to the mobile app.

Even though hub v2 has enough storage to handle larger packets, it appears ST chose to preserve backward compatibility with hub v1 which did not have enough storage or processing power.

Hopefully that helps. I’d love to hear from someone at ST about if this will ever be fixed for hub v2 but I doubt it.

1 Like