AVNET's iotconnect.io cloud platform is an online service that you can use to send data to, and then show it on a dashboard. In this blog series I'm learning the Python SDK and integrating BLE devices. In this post, two topics: how is the image retrieved from the OnSemi Smart Shot camera, and how is the image sent to the cloud.
image source: RSL10 Smart Shot Color Camera user's manual |
Getting the Image from the Camera via BLE
When the cloud application needs an image off the remote camera, it sends a command to the IIOTConnect SmartEdge Gateway.
image: when the cloud user interface requests an image from the camera, it generates a command to the camera (child) via the device (gateway)
This triggers a Python function on the gateway.
def SmartShotCaptureCmd(msg):
This happens via a callback mechanism that listens for cloud commands:
# SDK call backs
def callbackMessageMyPythonSensorValue(msg):
global sdk, my_command_dict, d2cMsg
myprint(msg)
return
if msg != None and len(list(msg.items())) != 0:
cmdType = msg["cmdType"]
data = msg["data"]
# For non OTA(commands etc)
if cmdType != "0x02" and data != None:
#
# Put code here to do command
#
myprint("Message: " + str(msg))
if (msg['data']['command'] == ' SmartShotCaptureCmd'):
SmartShotCaptureCmd(data)
elif # ...
After looking up the correct child in the list of all BLE devices in reach of the gateway, a connection is made.
RSL10DataLock.acquire()
smartshot = btle.Peripheral(data.upper())
An image is retrieved and written to the gateway's file system
#Start capture
myprint("Start Capture " + datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.000Z"))
imagefp = 0
smartshot.setMTU(247)
smartshot.writeCharacteristic(ChControlUuid, struct.pack('<b', 0x01))
# Wait for capture complete notification
smartshot.waitForNotifications(5)
# Start image transfer
PhotoFrameLength = 14
smartshot.writeCharacteristic(ChControlUuid, struct.pack('<b', 0x04))
smartshot.waitForNotifications(2)
while (imagelength > 0) and ( count < 5000):
count = count + 1
imagelength = imagelength - PhotoFrameLength
smartshot.waitForNotifications(1)...
if ( count < 5000):
if (imagefp != 0):
myprint("ImageClosed")
imagefp.close()
Index = 0
NameIndex = 0
count = 0
for item in SmartShotIndex:
if (item[0] == str(data)):
Index = item[1]
SmartShotIndex[count] = [data, Index + 1]
count = count + 1
for item in AddressList:
if (item['addr'] == str(data)):
NameIndex = item['name']
photoname = str(uniqueId) + str(NameIndex) + "Capture" + str(Index) + ".jpg"
myprint(photoname)
os.system("mv capture.jpg " + photoname)
SmartShotVersion = -1
for item in AddressList:
if item['addr'] == data:
SmartShotVersion = item['applicationversion']
data1 = {
'SmartShotIndex':Index,
'SmartShotPhoto':photoname,
'SmartShotVersion':SmartShotVersion,
'SmartShotStatus':"Online"
}
if (type == 1):
packet = {
"uniqueId": "ONSemi" + data.replace(':', '')[6:].upper() + "SmartShotBlackWhite"+ uniqueId[:6],
"time": datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.000Z"),
"data": data1
}
OnBoard.SendDataNow(packet)
result = SendPhotoToCloud(photoname,"ONSemi" + data.replace(':', '')[6:].upper() + "SmartShotBlackWhite"+ uniqueId[:6])
else:
packet = {
"uniqueId": "ONSemi" + data.replace(':', '')[6:].upper() + "SmartShotColor"+ uniqueId[:6],
"time": datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.000Z"),
"data": data1
}
OnBoard.SendDataNow(packet)
result = SendPhotoToCloud(photoname,"ONSemi" + data.replace(':', '')[6:].upper() + "SmartShotColor"+ uniqueId[:6])
myprint("PhotoSent " + datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.000Z"))
os.system('rm ' + photoname)
result = 0
Sending the Captured Photo to the Cloud
One of the last lines of code in the previous section was the command to upload the image to the cloud:
result = SendPhotoToCloud(photoname,"ONSemi" + data.replace(':', '')[6:].upper() + "SmartShotColor"+ uniqueId[:6])
This function uses a custom web service on iotconnect.io to load that data.
http_photo_upload = https://onsemirslapi.iotconnect.io/api/device/addGatewayImage
When the image is sent, a number of attributes are added to the payload, like the gateway and child identifiers.
Then the image is loaded:
files = {'image': (name, open(name, 'rb'))}
response = requests.request("POST", url, data=payload, headers=headers, files=files)
response = response.json()
if ((response != None ) and (response['status'] == 200)):
return 0
else:
return 1
image: gui after I requested an image
image: data arriving
image: the command sent from cloud to gateway
.




