I look forward to speaking on AI on the Edge at DotNetSouth.Tech. This year is the conference’s first year so check it out.
AI on the Edge
I look forward to speaking on AI on the Edge at DotNetSouth.Tech. This year is the conference’s first year so check it out.
I am happy to announce I will speaking at the Orlando Code Camp again this year. I will be presenting AI on the Edge, a look into Microsoft’s Azure IoT Edge.
AI on the Edge
The next evolution in cloud computing is a smarter application not in the cloud. As the cloud has continued to evolve, the applications that utilize it have had more and more capabilities of the cloud. This presentation will show how to push logic and machine learning from the cloud to an edge application. Afterward, creating edge applications which utilize the intelligence of the cloud should become effortless.
After Izon announced that they were closing down their services (leaving the cameras I already owned useless), I decided to turn them into something useful using Azure. First let me list some resources:
Use the Will it hack link to get access to the mobileye website and verify that the Izon device is still streaming and still working. If it is working, you are already done with edits to the device unless you would like to change the passwords (which you should).
Our goals are as follows:
These are all stretch goals that will be referred back to as the project moves forward.
For the first module, we will use the C Module base image. We are looking for two things from this module:
If you don’t know where to get started with the C module of the Azure IoT Edge platform, there is helpful information on the Azure Documentation page. Once the C module is created and ready for editing, we are going to connect to the image feed from the devices. To make this simple, both feeds will be retrieved using HTTP. For the video feed, its simple enough to grab images from the Izon camera existing camera feed.
Now one thing we need, is to be able to connect to each camera within the local network shared with the Edge. Since we would like to be able to add and remove cameras, we will use the device twin to update and manage the list of IP address. The code for updating the list is as follows:
#include <stdio.h> | |
#include <stdlib.h> | |
#include "iothub_module_client_ll.h" | |
#include "iothub_client_options.h" | |
#include "iothub_message.h" | |
#include "azure_c_shared_utility/threadapi.h" | |
#include "azure_c_shared_utility/crt_abstractions.h" | |
#include "azure_c_shared_utility/platform.h" | |
#include "azure_c_shared_utility/shared_util_options.h" | |
#include "iothubtransportmqtt.h" | |
#include "iothub.h" | |
#include "time.h" | |
#include "parson.h" | |
typedef struct IP_ADDRESS_NODE | |
{ | |
const char * address; | |
struct IP_ADDRESS_NODE * next; | |
} ip_address_node; | |
ip_address_node * add_address(const char * address,ip_address_node * previous) | |
{ | |
ip_address_node * new_node = (ip_address_node *)malloc(sizeof(ip_address_node)); | |
new_node->address = address; | |
new_node->next = NULL; | |
if (previous == NULL) | |
{ | |
return new_node; | |
} | |
previous->next = new_node; | |
return previous; | |
} | |
void delete_address(ip_address_node * current) | |
{ | |
if (current == NULL) | |
{ | |
return; | |
} | |
delete_address(current->next); | |
//free(current->address); | |
free(current); | |
} | |
ip_address_node * root_node = NULL; | |
ip_address_node * add_address_to_root(const char * address) | |
{ | |
if (root_node = NULL) | |
{ | |
root_node = add_address(address,root_node); | |
} | |
ip_address_node * current = root_node; | |
while(current->next != NULL) | |
{ | |
current = current->next; | |
} | |
add_address(address,current); | |
} | |
static void moduleTwinCallback(DEVICE_TWIN_UPDATE_STATE update_state, const unsigned char* payLoad, size_t size, void* userContextCallback) | |
{ | |
printf("\r\nTwin callback called with (state=%s, size=%zu):\r\n%s\r\n", | |
ENUM_TO_STRING(DEVICE_TWIN_UPDATE_STATE, update_state), size, payLoad); | |
JSON_Value *root_value = json_parse_string(payLoad); | |
JSON_Object *root_object = json_value_get_object(root_value); | |
JSON_Array * ipaddresses = json_object_dotget_array(root_object, "desired.CameraAddresses"); | |
if (ipaddresses != NULL) { | |
delete_address(root_node); | |
for (int i = 0; i < json_array_get_count(ipaddresses); i++) { | |
add_address_to_root(json_array_get_string(ipaddresses,i)); | |
} | |
return; | |
} | |
ipaddresses = json_object_get_array(root_object, "CameraAddresses"); | |
if (ipaddresses != NULL) { | |
delete_address(root_node); | |
for (int i = 0; i < json_array_get_count(ipaddresses); i++) { | |
add_address_to_root(json_array_get_string(ipaddresses,i)); | |
} | |
return; | |
} | |
} |
With that code in place, the list of IP addresses can be updated from the Azure UI and the Azure Service SDKs.
The Izon cameras make downloading the image feed trivial. There is an existing endpoint where you can grab the latest image directly from the camera’s web server. The latest image is always at /cgi-bin/img-d1.cgi. (NOTE: if you are checking this image from a browser, be sure to have some cache busting!). To download this image into our module, we will use the Curl library for it’s easy HTTP implementation. To add Curl to our Edge module, we will add the following lines to the Dockerfile.amd64.debug:
FROM ubuntu:xenial AS base | |
RUN apt-get update && \ | |
apt-get install -y –no-install-recommends software-properties-common gdb && \ | |
add-apt-repository -y ppa:aziotsdklinux/ppa-azureiot && \ | |
apt-get update && \ | |
apt-get install -y azure-iot-sdk-c-dev && \ | |
rm -rf /var/lib/apt/lists/* | |
FROM base AS build-env | |
RUN apt-get update && \ | |
apt-get install -y –no-install-recommends cmake gcc g++ make libcurl4-openssl-dev && \ | |
rm -rf /var/lib/apt/lists/* | |
WORKDIR /app | |
COPY . ./ | |
RUN cmake -DCMAKE_BUILD_TYPE=Debug . | |
RUN make | |
FROM base | |
WORKDIR /app | |
COPY –from=build-env /app ./ | |
CMD ["./main"] |
FROM ubuntu:xenial AS base | |
RUN apt-get update && \ | |
apt-get install -y –no-install-recommends software-properties-common gdb && \ | |
add-apt-repository -y ppa:aziotsdklinux/ppa-azureiot && \ | |
apt-get update && \ | |
apt-get install -y azure-iot-sdk-c-dev && \ | |
rm -rf /var/lib/apt/lists/* | |
FROM base AS build-env | |
RUN apt-get update && \ | |
apt-get install -y –no-install-recommends cmake gcc g++ make && \ | |
rm -rf /var/lib/apt/lists/* | |
WORKDIR /app | |
COPY . ./ | |
RUN cmake -DCMAKE_BUILD_TYPE=Debug . | |
RUN make | |
FROM base | |
WORKDIR /app | |
COPY –from=build-env /app ./ | |
CMD ["./main"] |
With curl now added to the image, it can be utilized in code by adding it to the method invoked in our main loop. The code will download the file for each entry in the IP address list. Once the image is downloaded, it will send it as a message to the Edge Hub and add the IP address of the camera to the message header. Here is that code:
struct MemoryStruct { | |
char *memory; | |
size_t size; | |
}; | |
static size_t | |
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) | |
{ | |
size_t realsize = size * nmemb; | |
struct MemoryStruct *mem = (struct MemoryStruct *)userp; | |
char *ptr = realloc(mem->memory, mem->size + realsize + 1); | |
if(ptr == NULL) { | |
/* out of memory! */ | |
printf("not enough memory (realloc returned NULL)\n"); | |
return 0; | |
} | |
mem->memory = ptr; | |
memcpy(&(mem->memory[mem->size]), contents, realsize); | |
mem->size += realsize; | |
mem->memory[mem->size] = 0; | |
return realsize; | |
} | |
struct MemoryStruct download_file(const char * address) | |
{ | |
struct MemoryStruct chunk; | |
chunk.memory = malloc(1); /* will be grown as needed by the realloc above */ | |
chunk.size = 0; /* no data at this point */ | |
/* init the curl session */ | |
CURL * curl_handle = curl_easy_init(); | |
/* specify URL to get */ | |
curl_easy_setopt(curl_handle, CURLOPT_URL, address); | |
/* send all data to this function */ | |
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); | |
/* we pass our 'chunk' struct to the callback function */ | |
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk); | |
/* some servers don't like requests that are made without a user-agent | |
field, so we provide one */ | |
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0"); | |
/* get it! */ | |
CURLcode res = curl_easy_perform(curl_handle); | |
/* check for errors */ | |
if(res != CURLE_OK) { | |
fprintf(stderr, "curl_easy_perform() failed: %s\n", | |
curl_easy_strerror(res)); | |
} | |
/* cleanup curl stuff */ | |
curl_easy_cleanup(curl_handle); | |
return chunk; | |
} | |
void download_image(IOTHUB_MODULE_CLIENT_LL_HANDLE iotHubModuleClientHandle) | |
{ | |
ip_address_node * address_node = root_node; | |
do | |
{ | |
struct MemoryStruct image = download_file(address_node->address); | |
if (image.size > 1) | |
{ | |
IOTHUB_MESSAGE_HANDLE message_handle = IoTHubMessage_CreateFromByteArray((char*)image.memory, image.size); | |
MAP_HANDLE propMap = IoTHubMessage_Properties(message_handle); | |
Map_AddOrUpdate(propMap, "IpAddress", address_node->address); | |
IOTHUB_CLIENT_RESULT clientResult = IoTHubModuleClient_LL_SendEventToOutputAsync(iotHubModuleClientHandle, message_handle, "IncomingImage", NULL,NULL); | |
if (clientResult != IOTHUB_CLIENT_OK) | |
{ | |
IoTHubMessage_Destroy(message_handle); | |
printf("IoTHubModuleClient_LL_SendEventToOutputAsync failed on sending to output IncomingImage, err=%d\n", clientResult); | |
} | |
} | |
free(image.memory); | |
address_node = address_node->next; | |
} while(address_node != NULL); | |
} |
Now that the image feed is being published to the Edge Hub, its time to connect the audio feed. The audio feed is trickier since the Izon camera doesn’t have an easy to use endpoint (that I know of) for downloading the audio samples like we can with the image feed. In the next entry in this series, an Audio feed will be derived from an RSTP stream.
If you are looking for a guide on creating an Open CV module in Python, check out a guide here. This guide will focus on creating an Azure IoT Edge module in C++. To accomplish this we need to take the following steps:
This article assumes that you use a computer or virtual machine running Windows or Linux as your development machine. And you simulate your IoT Edge device on your development machine.
To create a module, you need Docker to build the module image, and a container registry to hold the module image:
Take these steps to create an IoT Edge module based on Azure IoT C SDK using Visual Studio Code and the Azure IoT Edge extension. First you create a solution, and then you generate the first module in that solution. Each solution can contain more than one module.
VS Code takes the information you provided, creates an IoT Edge solution, and then loads it in a new window.
There are four items within the solution:
Note
The environment file is only created if you provide an image repository for the module. If you accepted the localhost defaults to test and debug locally, then you don’t need to declare environment variables.
The default C module code that comes with the solution is located at modules >  > main.c. The module and the deployment.template.json file are set up so that you can build the solution, push it to your container registry, and deploy it to a device to start testing without touching any code. The module is built to simply take input from a source (in this case, the tempSensor module that simulates data) and pipe it to IoT Hub.
When you’re ready to customize the C template with your own code, use the Azure IoT Hub SDKs to build modules that address the key needs for IoT solutions such as security, device management, and reliability.
In each module folder, there are several Docker files for different container types. Use any of these files that end with the extension .debug to build your module for testing. Currently, C modules support debugging only in Linux amd64 containers.
deployment.template.json
 file. Update your module image URL by adding .debug to the end."createOptions": "{\"HostConfig\": {\"Privileged\": true}}"
deployment.template.json
 file for your solution from the command palette.deployment.json
 file. Choose Select Edge Deployment Manifest.You’ll see the deployment successfully created with a deployment ID in a VS Code-integrated terminal.
Check your container status in the VS Code Docker explorer or by running the docker ps
 command in the terminal.
VS Code keeps debugging configuration information in a launch.json
 file located in a .vscode
 folder in your workspace. This launch.json
 file was generated when you created a new IoT Edge solution. It updates each time you add a new module that supports debugging.
main.c
. Add a breakpoint in this file.The preceding example shows how to debug C IoT Edge modules on containers. It added exposed ports in your module container createOptions. After you finish debugging your Node.js modules, we recommend you remove these exposed ports for production-ready IoT Edge modules.
The working environment is an Ubuntu 18.04 64 bit Desktop OS running Clion using an embedded version of CMake 3.10. Open CV is added via source as a submodule to the project and added as a package in the CMakeLists.txt with the following line:
FIND_PACKAGE (OpenCV REQUIRED)
Once that was added to the CMakeLists.txt, the main.cpp file was changed to the following code:
#include <opencv2/opencv.hpp> | |
int main( int argc, char** argv ) | |
{ | |
VideoCapture cap; | |
if(!cap.open(0)) | |
return 0; | |
Mat frame; | |
cap >> frame; | |
//Do something with the frame | |
} |
Once you create IoT Edge modules with your business logic, you want to deploy them to your devices to operate at the edge. If you have multiple modules that work together to collect and process data, you can deploy them all at once and declare the routing rules that connect them.
This article shows how to create a JSON deployment manifest, then use that file to push the deployment to an IoT Edge device. For information about creating a deployment that targets multiple devices based on their shared tags, see Deploy and monitor IoT Edge modules at scale
A deployment manifest is a JSON document that describes which modules to deploy, how data flows between the modules, and desired properties of the module twins. For more information about how deployment manifests work and how to create them, see Understand how IoT Edge modules can be used, configured, and reused.
To deploy modules using Visual Studio Code, save the deployment manifest locally as a .JSON file. You will use the file path in the next section when you run the command to apply the configuration to your device.
Here’s a basic deployment manifest with one module as an example:
{
"modulesContent": {
"$edgeAgent": {
"properties.desired": {
"schemaVersion": "1.0",
"runtime": {
"type": "docker",
"settings": {
"minDockerVersion": "v1.25",
"loggingOptions": "",
"registryCredentials": {}
}
},
"systemModules": {
"edgeAgent": {
"type": "docker",
"settings": {
"image": "mcr.microsoft.com/azureiotedge-agent:1.0",
"createOptions": "{}"
}
},
"edgeHub": {
"type": "docker",
"status": "running",
"restartPolicy": "always",
"settings": {
"image": "mcr.microsoft.com/azureiotedge-hub:1.0",
"createOptions": "{}"
}
}
},
"modules": {
"tempSensor": {
"version": "1.0",
"type": "docker",
"status": "running",
"restartPolicy": "always",
"settings": {
"image": "mcr.microsoft.com/azureiotedge-simulated-temperature-sensor:1.0",
"createOptions": "{}"
}
}
}
}
},
"$edgeHub": {
"properties.desired": {
"schemaVersion": "1.0",
"routes": {
"route": "FROM /* INTO $upstream"
},
"storeAndForwardConfiguration": {
"timeToLiveSecs": 7200
}
}
},
"tempSensor": {
"properties.desired": {}
}
}
}
You can use the Azure IoT extensions for Visual Studio Code to perform operations with your IoT hub. For these operations to work, you need to sign in to your Azure account and select the IoT hub that you are working on.
You deploy modules to your device by applying the deployment manifest that you configured with the module information.
The results of your deployment are printed in the VS Code output. Successful deployments are applied within a few minutes if the target device is running and connected to the internet.
Once you’ve deployed modules to your device, you can view all of them in the Azure IoT Hub Devices section. Select the arrow next to your IoT Edge device to expand it. All the currently running modules are displayed.
If you recently deployed new modules to a device, hover over the Azure IoT Hub Devices section header and select the refresh icon to update the view.
Right-click the name of a module to view and edit the module twin.
Google’s Protocol Buffers are a perfect fit with the multilingual approach of Azure IoT Edge. Using ProtoBuf, a message format can be written once and used across multiple frameworks and languages while benefiting from the speed and message size intrinsic to ProtoBuf. For this Azure IoT Edge use case, we will generate a message in C++ and send it to a module written in Python to filter out the values that are sent to IoT Hub.
Creating the message format is trivial. Following the language guide, there are two message types to create.
syntax = "proto3"; message TemperatureReading { int reading = 1; string timestamp = 2; } message TemperatureReadingUpload { string uploaded_timestamp = 1; repeated TemperatureReading readings = 2; }
The above is all that is needed to create the model for ProtoBuf. Creating the language specific code for each module is covered in their module sections.
This article assumes that you use a computer or virtual machine running Windows or Linux as your development machine. And you simulate your IoT Edge device on your development machine.
To create a module, you need Docker to build the module image, and a container registry to hold the module image:
Take these steps to create an IoT Edge module based on Azure IoT C SDK using Visual Studio Code and the Azure IoT Edge extension. First you create a solution, and then you generate the first module in that solution. Each solution can contain more than one module.
VS Code takes the information you provided, creates an IoT Edge solution, and then loads it in a new window.
There are four items within the solution:
Note
The environment file is only created if you provide an image repository for the module. If you accepted the localhost defaults to test and debug locally, then you don’t need to declare environment variables.
The default C module code that comes with the solution is located at modules >> main.c. The module and the deployment.template.json file are set up so that you can build the solution, push it to your container registry, and deploy it to a device to start testing without touching any code. The module is built to simply take input from a source (in this case, the tempSensor module that simulates data) and pipe it to IoT Hub.
When you’re ready to customize the C template with your own code, use the Azure IoT Hub SDKs to build modules that address the key needs for IoT solutions such as security, device management, and reliability.
To compile the Protocol Buffer file, use the command line compiler protoc. For more information on how to use protoc for each platform, check out the Protocol Buffer documentation. For the C module, we will use the C++ compiler options:
protoc --proto_path=src --cpp_out=model src/temp.proto
To create and serialize the object, use the following code:
TemperatureReading reading; reading.set_reading(get_temperature_reading()); //get_temperature_reading is your function on generating the temperature reading value auto message_body = reading.SerializeAsString();
In each module folder, there are several Docker files for different container types. Use any of these files that end with the extension .debug to build your module for testing. Currently, C modules support debugging only in Linux amd64 containers.
deployment.template.json
 file. Update your module image URL by adding .debug to the end."createOptions": "{\"HostConfig\": {\"Privileged\": true}}"
deployment.template.json
 file for your solution from the command palette.deployment.json
 file. Choose Select Edge Deployment Manifest.You’ll see the deployment successfully created with a deployment ID in a VS Code-integrated terminal.
Check your container status in the VS Code Docker explorer or by running the docker ps
 command in the terminal.
VS Code keeps debugging configuration information in a launch.json
 file located in a .vscode
 folder in your workspace. This launch.json
 file was generated when you created a new IoT Edge solution. It updates each time you add a new module that supports debugging.
main.c
. Add a breakpoint in this file.The preceding example shows how to debug C IoT Edge modules on containers. It added exposed ports in your module container createOptions. After you finish debugging your C modules, we recommend you remove these exposed ports for production-ready IoT Edge modules.
The following steps create an IoT Edge Python module by using Visual Studio Code and the Azure IoT Edge extension.
Use the Python package cookiecutter to create a Python solution template that you can build on top of.
pip install --upgrade --user cookiecutter
Ensure the directory where cookiecutter will be installed is in your environment’s Path
 in order to make it possible to invoke it from a command prompt.
The VS Code window loads your IoT Edge solution workspace: the modules folder, a deployment manifest template file, and a .env file.
The environment file stores the credentials for your container repository and shares them with the IoT Edge runtime. The runtime needs these credentials to pull your private images onto the IoT Edge device.
To compile the Protocol Buffer file, use the command line compiler protoc. For more information on how to use protoc for each platform, check out the Protocol Buffer documentation. For the Python module, we will use the Python compiler options:
protoc --proto_path=src --python_out=model src/temp.proto
Each template includes sample code, which takes simulated sensor data from the tempSensor module and routes it to the IoT hub. In this section, add the code that expands the PythonModule to analyze the messages before sending them.
import temp_pb3
TEMPERATURE_THRESHOLD = 25
TWIN_CALLBACKS = 0
# receive_message_callback is invoked when an incoming message arrives on the specified
# input queue (in the case of this sample, "input1"). Because this is a filter module,
# we forward this message to the "output1" queue.
def receive_message_callback(message, hubManager):
global RECEIVE_CALLBACKS
global TEMPERATURE_THRESHOLD
message_buffer = message.get_bytearray()
map_properties = message.properties()
key_value_pair = map_properties.get_internals()
print ( " Properties: %s" % key_value_pair )
RECEIVE_CALLBACKS += 1
print ( " Total calls received: %d" % RECEIVE_CALLBACKS )
data = TemperatureReading.ParseFromString(message_buffer)
if data.reading > TEMPERATURE_THRESHOLD:
map_properties.add("MessageType", "Alert")
print("Machine temperature %s exceeds threshold %s" % (data["machine"]["temperature"], TEMPERATURE_THRESHOLD))
hubManager.forward_event_to_output("output1", message, 0)
return IoTHubMessageDispositionResult.ACCEPTED
# module_twin_callback is invoked when the module twin's desired properties are updated.
def module_twin_callback(update_state, payload, user_context):
global TWIN_CALLBACKS
global TEMPERATURE_THRESHOLD
print ( "\nTwin callback called with:\nupdateStatus = %s\npayload = %s\ncontext = %s" % (update_state, payload, user_context) )
data = json.loads(payload)
if "desired" in data and "TemperatureThreshold" in data["desired"]:
TEMPERATURE_THRESHOLD = data["desired"]["TemperatureThreshold"]
if "TemperatureThreshold" in data:
TEMPERATURE_THRESHOLD = data["TemperatureThreshold"]
TWIN_CALLBACKS += 1
print ( "Total calls confirmed: %d\n" % TWIN_CALLBACKS )
# Sets the callback when a module twin's desired properties are updated.
self.client.set_module_twin_callback(module_twin_callback, self)
In the previous section, you created an IoT Edge solution and added code to the PythonModule to filter out messages where the reported machine temperature is below the acceptable threshold. Now you need to build the solution as a container image and push it to your container registry.
docker login -u <ACR username> -p <ACR password> <ACR login server>
Use the username, password, and login server that you copied from your Azure container registry in the first section. You can also retrieve these values from the Access keys section of your registry in the Azure portal.
"PythonModule": {
"properties.desired":{
"TemperatureThreshold":25
}
}
When you tell Visual Studio Code to build your solution, it first takes the information in the deployment template and generates a deployment.json file in a new folder named config. Then it runs two commands in the integrated terminal: docker build
 and docker push
. These two commands build your code, containerize the Python code, and then push the code to the container registry that you specified when you initialized the solution.
You can see the full container image address with tag in the docker build
 command that runs in the VS Code integrated terminal. The image address is built from information in the module.json file with the format <repository>:<version>-<platform>. For this tutorial, it should look like registryname.azurecr.io/pythonmodule:0.0.1-amd64.
You can use the Azure portal to deploy your Python module to an IoT Edge device like you did in the quickstarts. You can also deploy and monitor modules from within Visual Studio Code. The following sections use the Azure IoT Edge extension for VS Code that was listed in the prerequisites. Install the extension now, if you didn’t already.
The interview I had with .NET Rocks! is here.
After my sessions at Update Conference Prague I will be discussing the Azure IoT Edge platform with .NET Rocks!. Hopefully I will have recovered from jet lag and my other presentations to give a coherent and passable interview. One of the questions they asked me was, what hardware would I buy if I had $5000 to spend on it?
The Azure IoT Edge getting started guide currently utilizes VS Code and Docker to create modules. If you receive “docker.sock connect: permission denied” after trying to build, run the following two commands in the terminal:
sudo usermod -aG docker $USER
newgrp docker
If you still have the error, restart your machine and try again.
I have been selected to speak at Update Conference Prague duringÂ
Being able to run compute cycles on local hardware is a practice predating silicon circuits. Mobile and Web technology has pushed computation away from local hardware and onto remote servers. As prices in the cloud have decreased, more and more of the remote servers have moved there. This technology cycle is coming full circle with pushing the computation that would be done in the cloud down to the client. The catalyst for the cycle completing is latency and cost. Running computations on local hardware softens the load in the cloud and reduces overall cost and architectural complexity.
The difference now is how the computational logic is sent to the device. As of now, we rely on app stores and browsers to deliver the logic the client will use. Delivery mechanisms are evolving into writing code once and having the ability to run that logic in the cloud and push that logic to the client through your application and have that logic run on the device. In this presentation, we will look at how to accomplish this with existing Azure technologies and how to prepare for upcoming technologies to run these workloads.
Using IoT Devices, powered by Windows 10 IoT and Raspbian, we can collect data from the world surrounding us. That data can be used to create interactive environments for mixed reality, augmented reality, or virtual reality. To move the captured data from the devices to the interactive environment, the data will travel through Microsoft’s Azure. First it will be ingested through the Azure IoT Hub which provides the security, bi-directional communication, and input rates needed for the solution. We will move the data directly from the IoT Hub to an Azure Service Bus Topic. The Topic allows for data to be sent to every Subscription listening for the data that was input. Azure Web Apps subscribe to the Topics and forward the data through a SignalR Hub that forwards the data to a client. For this demo, the client is a Unity Application that creates a Virtual Reality simulation showcasing that data.
Once finished with this introduction to these technologies, utilizing each component of this technology stack should be approachable. Before seeing the pieces come together, the technologies used in this demonstration may not seem useful to a developer. When combined, they create a powerful tool to share nearly unlimited amounts of incoming data across multiple channels.
Proudly, I will be entering my second year as a Microsoft MVP. This will be under the Microsoft Azure category again. Moving forward, I look forward to doing a large amount of work and training with Azure Edge and Azure ML. Specifically, I look forward to working on the Scry Unlimited and West World of Warcraft projects. To contact me for for your project, please visit the contact page.
As a start, on 7/2/2018 I will be presenting AI on the Edge at the Atlanta Intelligent Devices user group. Following that up I will be speaking at events around the country and hopefully internationally. In addition to my normal speaking on Mobile, Cloud, and Edge; I will be adding Machine Learning and Artificial Intelligence specifically focusing on the integration with Edge and Mobile computing. If you are looking for a speaker, check out my speaker page and fill out the form.
Finally, I am still putting together events in Atlanta. If you would like to participate in any of the following events, just follow their links or message me on Twitter: