Giter Site home page Giter Site logo

juunas11 / azurelocationtrackingdemo Goto Github PK

View Code? Open in Web Editor NEW
2.0 2.0 0.0 184 KB

Sample application that shows simulated location data on a map view

License: MIT License

PowerShell 20.12% Bicep 32.93% TSQL 1.10% HTML 0.20% Vue 8.61% TypeScript 4.38% CSS 0.06% C# 32.21% Dockerfile 0.40%

azurelocationtrackingdemo's Introduction

Azure Location Tracking Demo application

This sample application implements a data pipeline from IoT devices to a Vue front-end. Azure services used:

  • IoT Hub
  • Device Provisioning Service
  • Event Hub
  • Azure Data Explorer
  • Function App
  • SignalR Service
  • Azure Maps
  • Azure SQL DB
  • Container App
  • Container Registry
  • Application Insights
  • Log Analytics

Deploying the demo

Prerequisites:

  • Resource group in an Azure subscription, your user must have Owner role in the resource group
    • The script does create the resource group if it does not exist, but then you need Owner role on the subscription
  • At least Application Developer role in Entra ID (Azure AD) tenant
    • This can be a different tenant from the one where resources are deployed to
  • Docker (script uses docker CLI)
  • Azure CLI
    • azure-iot extension
  • PowerShell
    • Microsoft.Graph module
    • SqlServer module
  • Node.js (tested with 20.11.1)

To deploy the application in your own Azure subscription, first rename deployment/config.sample.json to deployment/config.json. Then fill in at least these settings:

  • tenantId
    • Entra ID (Azure AD) tenant ID where the Azure subscription is
  • subscriptionId
    • Azure subscription where resources will be deployed to
  • resourceGroup
    • Resource group where resources will be deployed to
  • location
    • Azure region where resources will be deployed to (e.g. westeurope)
  • developerUserId
    • Your user object ID in the Entra ID (Azure AD) tenant where resources are deployed to
    • Used to assign container registry push, SQL admin, Maps reader, ADX admin, and IotHub Twin contributor rights
  • developerUsername
    • Your user name in the Entra ID (Azure AD) tenant where resources are deployed to
    • Used to assign SQL admin username
  • developerIpAddress
    • Your IP address
    • Traffic from this URL is allowed into SQL DB
  • adApplicationTenantId
    • Entra ID (Azure AD) tenant ID where an app registration is setup for the Function App
    • This app registration enables logging in to the front-end; logged in users can modify device parameters
    • This can be a different tenant from the one where resources are
  • adApplicationUri
    • Identifier URI for the app registration, used to match to existing registration when running script again
    • Typically something like: https://mytenant.onmicrosoft.com/AzureLocationTrackingDemo

You can also change the default settings for the SignalR hub names and DPS enrolmment group names, but you can leave those at defaults.

Now that we have finished configuration, you can run the script:

.\deployment\Deploy.ps1

Running the script for the first time can take at least 15 minutes.

Note that you must run the script twice to get everything deployed. This only applies for the first run. If you make changes and want to redeploy, just run the deployment script again.

Running the demo

The deployment script will output the Function App URL. Open the URL in a browser and you should see the map. By default, the map will be centered on hard-coded coordinates. The deployment script will also seed one or more geofences that you should be able to see on the map.

The Container App is setup with a 0-1 scale rule by default, which should mean it runs one replica for a while after creation and then scales to zero. To run simulators and cause vehicles to appear on the map, scale up to at least 1 replica.

You can also log in, and this allows you to modify the speed and location update interval of a vehicle.

The deployment script also creates an Azure dashboard that you can check to see statistics for the demo.

Running locally

Prerequisites:

  • Run the deployment script
  • Azurite
  • Ngrok
  • SQL database
  • Ability to run .NET Azure Functions (.NET 8)
  • Node.js (tested with 20.11.1)

From the deployment script outputs, you should get the necessary user secrets to configure and run both .NET applications:

  • AzureLocationTracking.Functions
    • Function App that hosts the front-end and acts as its back-end, also processes Event Hub messages
  • AzureLocationTracking.VehicleSimulator
    • Device simulator that sends events to IoT Hub, which then get forwarded to the Function App

Note that the SQL database connection string is missing from these, you will need to specify one yourself.

You will also need to run:

.\deployment\SetupLocalFrontend.ps1

This sets up the Entra ID (Azure AD) identifiers as well as the Azure Maps client ID.

Then you can run scripts to start Azurite and Ngrok:

.\deployment\RunAzurite.ps1
.\deployment\RunNgrok.ps1

You can of course run these tools separately as well, but note that the Ngrok script additionally sets up the necessary SignalR Service upstream URL so that SignalR messages from the front-end reach your back-end.

You can then run the front-end in src\AzureLocationTracking.Frontend with:

npm install
npm run dev

There is an additional AzureLocationTracking.SignalRReceiver project that acts as a client, you can use it to see the data that a front-end receives.

How it works

In this demo application, the data flow starts from the Container App, which runs the vehicle simulator. This simulator uses a set of predefined routes in routes.json, from which it selects one at random. It starts "moving" from a random point on the route, at a speed of 50 km/h, reporting its latest location every 5 seconds.

In order to send data, the simulator first contacts Device Provisioning Service, from which it gets connection details to the IoT Hub. It is also registered as a device in IoT Hub at this point.

The simulator subscribes to device twin updates from the IoT hub. Through this, a logged in user is able to modify the speed and location update interval of a device.

The IoT Hub is setup to route all device messages to an Event Hub. There are actually two Event Hubs, one for development and one for production. The IoT Hub device twin for each device has an environment tag, that is used in routing rules.

The Event Hubs have three listeners: Azure Data Explorer, geofence update function, and location update function. ADX writes all events to a table. The geofence update function checks if the new location puts the vehicle inside a geofence it wasn't already in, and fires an event through SignalR for it. The location update function updates the latest location for the vehicle in the SQL database and fires an event through SignalR.

The Vue front-end's files are deployed inside the Function App and it returns the index.html file when you hit the root of the Function App. The front-end then connects to the Function App for a SignalR connection, which gets forwarded to SignalR Service. Since we are running SignalR Service in Serverless mode, any messages from the front-end back to the Function App get sent through a Webhook (called an "upstream" in SignalR Service).

The front-end is not interested in location update events that happen in an area of the map the user is not looking at. This is mostly a performance optimization. To achieve this, when the app loads and whenever the map is moved, we figure out which "grid squares" are visible in the map. Example grid square: [24, 60]. This defines a "square" (area on a spheroid) that includes all coordinates where the full degrees are 24 (longitude), 60 (latitude). A SignalR group is created for each grid square and the connection is added to them. If the user moves the map and the visible squares change, the group memberships are also updated.

If the user zooms out the map to the point where more than 50 grid squares are visible, we remove all of their memberships and do not add them to any of them. This is also a performance optimization so that the user would not receive too many updates.

Now when the Function App gets location updates, we only send SignalR events to the relevant grid square's group. Conveniently we can just round down both the latitude and longitude to get the grid square.

Cleaning up resources

To clean up Azure resources, delete the resource group. In addition, you can remove the app registration from the Entra ID (Azure AD) tenant.

azurelocationtrackingdemo's People

Contributors

juunas11 avatar joonaszure avatar

Stargazers

Pieter Vandenheede avatar Luis Mañez avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.