{"id":16946404,"url":"https://github.com/jsturtevant/iot-workshop","last_synced_at":"2026-05-18T02:36:27.016Z","repository":{"id":76039219,"uuid":"78665169","full_name":"jsturtevant/iot-workshop","owner":"jsturtevant","description":null,"archived":false,"fork":false,"pushed_at":"2017-05-31T18:14:42.000Z","size":1516,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-26T20:57:26.876Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jsturtevant.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-01-11T18:05:25.000Z","updated_at":"2023-08-29T10:54:39.000Z","dependencies_parsed_at":"2023-03-13T20:15:19.919Z","dependency_job_id":null,"html_url":"https://github.com/jsturtevant/iot-workshop","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jsturtevant/iot-workshop","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsturtevant%2Fiot-workshop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsturtevant%2Fiot-workshop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsturtevant%2Fiot-workshop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsturtevant%2Fiot-workshop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jsturtevant","download_url":"https://codeload.github.com/jsturtevant/iot-workshop/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsturtevant%2Fiot-workshop/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33162690,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-17T22:39:12.733Z","status":"online","status_checked_at":"2026-05-18T02:00:06.436Z","response_time":71,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-13T21:27:27.318Z","updated_at":"2026-05-18T02:36:27.000Z","avatar_url":"https://github.com/jsturtevant.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"#IoT Hub Workshop\n\nAt this workshop, we will establish guidance for building secure and scalable, device-centric solutions, conducting analysis and integrating into existing systems.  You will develop an IoT solution that collects data from a simulated device via an Azure IoT Hub gateway ingestion service, enables real-time processing through Azure Stream Analytics and explore options for integrating with back systems.  At the end of the workshop, you will walk away with a clear understanding of the key components to an Azure IoT solution that can help you facilitate valuable insights by harnessing the power of your untapped data.\n\nThe workshop is designed to introduce you to the many different components of an Azure IoT solution.  By the end you will have worked with all the major components and seen how they all fit together.  You could take the solution at the end of the workshop and build upon it for you specific scenario or you can look at one of the pre-built solutions that [Azure IoT Suite](https://www.azureiotsuite.com/) offers even more functionality.  This workshop will help you prepare for customize the Azure IoT Suite solutions.\n\nThe workshop is broken down into several steps:\n\n1. Create IoT Hub in Azure\n2. Create Simulated device\n3. Create Azure Stream Analytics\n4. Add Cold Path\n5. Add Hot Path\n6. Add PowerBi Real-time Reporting\n\n## Before you begin\nThe Pre-requisites for the workshop are:\n\n- Azure Subscription (Can sign up for free at [Azure SignUp](https://azure.microsoft.com/en-us/free/?b=17.01) or [Visual Studio Dev Essentials](https://www.visualstudio.com/dev-essentials/))\n- Node.js \n- [Download IoT hub Explorer for Node.js](https://github.com/Azure/azure-iot-sdks/blob/master/doc/manage_iot_hub.md#iothub-explorer) \n- [Azure Storage Explorer](http://storageexplorer.com/) (optional)\n- [Download ServiceBus Explorer](https://github.com/paolosalvatori/ServiceBusExplorer/releases) (optional)\n\n## Create an IoT Hub in Azure\nLog into your portal at http://portal.azure.com and create a new IoT Hub by clicking on ```Plus sign-\u003eInternet Of Things-\u003eIot Hub```:\n\n![new iot hub in portal](https://github.com/jsturtevant/iot-workshop/blob/master/images/iot-new-iot-hub-portal.png)\n\nNext fill in the information on the IoT Hub Create Blade.  For the workshop select the ```Pricing and scale tier``` of free.  Create a new resource group called ```iot-workshop``` which we will place all our Azure resources in for this workshop and select a location near you.  Click ```Create``` and in a few minutes you will have your IoT Configured.\n\n![create new iot hub](https://github.com/jsturtevant/iot-workshop/blob/master/images/iot-new-iot-hub-create.png)\n\n## Create Simulated device\nIn this section we will [register a device in Azure IoT hub](#register-device) and then create a simulated device using the Node.Js (there are [c# samples here]().\n\n### Register Device\nAzure IoT hub has management API that can use to register devices and can be customized for your scenario.  In the case of the workshop will will be using a prebuilt tool called [IoT Hub Explorer](https://github.com/Azure/azure-iot-sdks/blob/master/doc/manage_iot_hub.md#iothub-explorer) that leverages the Management API's to register out simulated device.  The tool is [open source](https://github.com/Azure/iothub-explorer) so you can use it as an example if you need to develop more customized solution.  \n\nGet your Azure IoT Connection String from the portal ```All Resources-\u003eSelect your IoT Hub-\u003eShared Access policies```.  Here for the IoT Hub Explorer we will choose the connection string for the ```iothubowner``` to have full control but when working with other connections you should select the least  policy needed.\n\n![get azure IoT Hub connection string](https://github.com/jsturtevant/iot-workshop/blob/master/images/iot-new-iot-hub-connectionstring.png)\n\nOnce you have the tool installed open a command prompt and login to your IoT Hub:\n\n```\niothub-explorer login \u003cyour-iothub-connection-string\u003e\n```\n\nNext you can register your device using:\n\n```\niothub-explorer create workshopdevice --connection-string\n```\n\nYou can now see that device in the azure portal:\n\n![see the device created in portal](C:\\Projects\\workshops\\iot-quickstart\\images\\iot-new-iot-hub-device-created.png)\n\n### Create Simulated Node.Js \nNext create a file called ```simulateddevice.js``` in your project folder and add the following to it:\n\n```javascript\n'use strict';\n\nvar clientFromConnectionString = require('azure-iot-device-amqp').clientFromConnectionString;\nvar Message = require('azure-iot-device').Message;\n\nvar connectionString = 'HostName=\u003chubname\u003e.azure-devices.net;DeviceId=\u003cdeviceId\u003e;SharedAccessKey=\u003cyourkey\u003e';\n\nvar client = clientFromConnectionString(connectionString);\n\nfunction printResultFor(op) {\n  return function printResult(err, res) {\n    if (err) console.log(op + ' error: ' + err.toString());\n    if (res) console.log(op + ' status: ' + res.constructor.name);\n  };\n}\n\nvar connectCallback = function (err) {\n  if (err) {\n    console.log('Could not connect: ' + err);\n  } else {\n    console.log('Client connected');\n\n    // send random temp message every second\n    setInterval(function(){\n        var temp = 70 + (Math.random() * 20);\n        var data = JSON.stringify({ deviceId: 'simulatedDevice', temp: temp });\n        \n        var message = new Message(data);\n        console.log(\"Sending message: \" + message.getData());\n        client.sendEvent(message, printResultFor('send'));\n    }, 1000);\n\n\n    // set up Device listening for C2D\n    client.on('message', function (msg) {\n      console.log('Id: ' + msg.messageId + ' Body: ' + msg.data);\n      client.complete(msg, printResultFor('completed'));\n\n    });\n\n    // handle errors\n    client.on('error', function (err) {\n      console.error(err.message);\n    });\n\n    // handle disconnect\n    client.on('disconnect', function () {\n      clearInterval(sendInterval);\n      client.removeAllListeners();\n      client.open(connectCallback);\n    });\n  }\n};\n\n//start client\nclient.open(connectCallback);\n```\n\nNext run ```npm init -y``` to create a ```package.json``` file. Open the file and add the following dependencies:\n\n```\n \"dependencies\": {\n    \"azure-iot-device\": \"^1.0.15\",\n    \"azure-iot-device-amqp\": \"^1.0.15\"\n  }\n```\n\nInstall all the dependencies by running ```npm install```.\n\nGet your Device Connection string either from the command line when you created the device with the IoT Hub Explorer or in the portal at:\n\n![device connection string in portal](https://github.com/jsturtevant/iot-workshop/blob/master/images/iot-new-iot-hub-device-connectionstring.png)\n\nUpdate the connection string in the ```simulatedDevice.js``` file.\n\nFinally run your simulated device:\n\n```bash\nnode simulatedDevice.js\n# should see outputlike\nClient connected\nSending message: {\"deviceId\":\"simulatedDevice\",\"temp\":75.70230183395358}\nsend status: MessageEnqueued\nSending message: {\"deviceId\":\"simulatedDevice\",\"temp\":76.50387904219407}\nsend status: MessageEnqueued\nSending message: {\"deviceId\":\"simulatedDevice\",\"temp\":86.89145157479787}\nsend status: MessageEnqueued\nSending message: {\"deviceId\":\"simulatedDevice\",\"temp\":76.26535003653802}\nsend status: MessageEnqueued\n```\n\n## Create Azure Stream Analytics\nAfter created the simulated device we now ready to integrate the data into our back processing.  In a real scenario the data will becoming ingested into Azure IoT Hub at a large rate.  If you have 1000 devices in the field sending 1 message a second you would have 60,000 messages a minute being ingested into Azure IoT hub.  It is not uncommon to have many more devices.  Azure IoT Hub is designed to manage high volume through the use of partitions and Scale Units.\n\nIn many IoT solutions it is common to have a Hot and Cold path.  In the cold path you would dump the raw or aggregated data into storage for later analysis or processing.  The Hot path is typically used for alerts of critical parts of the system.  For instance in the workshop if the temperature is over 80 degrees we want to send a notification to so we can act and potentially resolve any issues.  To process the data on this Hot Path we need a real-time high through put system.  This is where Azure Stream Analytics comes in to play.  \n\n\u003e You can also write your own processors for custom logic.  Check out [this sample](https://github.com/codefoster/simple-azure-iot-hub/tree/master/service).\n\nTo create a Azure Stream Analytics job open the Azure portal and click ```Plus sign-\u003eInternet Of Things-\u003eStream Analytics job```.  Give the job a name and it to the same resource group and region as before.  Then click ```Create``` and shortly you will have a new job.\n\n![create azure stream analytics job](https://github.com/jsturtevant/iot-workshop/blob/master/images/iot-new-azure-stream-analytics-job.png)\n\n### Add IoT Hub Input\nAdding the IoT Hub input is easy as Azure has a fast integration setup between Azure Stream Analytics and Azure IoT Hub.  Click ```All resources-\u003eyour stream analytics job -\u003e overview -\u003e inputs -\u003e Add```.  Fill in the information for the Input using the IoT Hub from this subscription, use the ```service``` shared access policy and click create.  Optionally you could create a new Consumer Group in IoT hub for this instance of Azure Stream Analytics and selected that in this input creation.  Learn more about [device messaging](https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-messaging) and [consumer groups](https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-overview.)  \n\n![create azure stream analytics iothub input](https://github.com/jsturtevant/iot-workshop/blob/master/images/iot-new-azure-stream-analytics-job-iot-input.png)\n\n## Add Cold Path \nTo store data for later processing we will create a storage account and dump all the telemetry data to blob storage.  Later we could add \noptional processing on that data for analytics with things like Azure Data Factory.\n\n### Blob Storage output\nCreate an Azure Stream analytics Output with blob storage.  You could use your own storage if you already have an existing.  In the case of the workshop we will create our own:\n\n![azure stream analytics blob storage cold path output](https://github.com/jsturtevant/iot-workshop/blob/master/images/iot-new-azure-stream-analytics-job-cold-output.png)\n\n### Create query for cold path\nNext we need to write our query to move all the data from IoT Hub to the blob storage. \n\n![cold path query](https://github.com/jsturtevant/iot-workshop/blob/master/images/iot-new-azure-stream-analytics-job-cold-output-query.png)\n\n## Add Hot Path\nOn the hot path we will do something a bit more interesting with our query to only trigger an event if the temperature is over 80 degrees.\n\n### Create Azure Queue \nTo store events we will you an Azure Queue. Depending on the scenario you can either use a Queue or EventHub.  \n\n![azure stream analytics queue hot path output](https://github.com/jsturtevant/iot-workshop/blob/master/images/iot-new-azure-stream-analytics-job-hot-output.png)\n\n### Create query for Hot Path\nNext we need to write our query to trigger an alert for any temperature over 80 degrees.\n\n![hot path query](https://github.com/jsturtevant/iot-workshop/blob/master/images/iot-new-azure-stream-analytics-job-hot-output-query.png)\n\n### Start Azure Stream Analytics\nNow that we have all of our inputs, outputs, and queries created we can start the job.  Note that you can not edit the job while it is running.  It takes a few moments to start the job.\n\n![start job](https://github.com/jsturtevant/iot-workshop/blob/master/images/iot-new-azure-stream-analytics-job-start.png)\n\n### Review Cold path data\nYou can use the [Azure Storage Explorer](http://storageexplorer.com/) to view the data from the cold path.\n\n### Create an Azure Function to Process Hot Path\nThere are many ways to process the data for the Hot Path.  One of the easiest with with Azure Functions as they have built in integrations, scale well, and you only pay for what you use.\n\nCreate a new Azure Function App:\n\n![azure function app](https://github.com/jsturtevant/iot-workshop/blob/master/images/iot-function-app.png)\n\nCreate a new function for Service Bus Queue.  You will need to get your Service Bus Queue connection string (todo).\n\n![azure function app function for service ](https://github.com/jsturtevant/iot-workshop/blob/master/images/iot-function-app-create-function.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjsturtevant%2Fiot-workshop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjsturtevant%2Fiot-workshop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjsturtevant%2Fiot-workshop/lists"}