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
.