Git Product home page Git Product logo

azure-adt-example's Introduction

Azure Digital Twin Query API

codecov

This is a sample project I created to learn Go. There's an existing SDK for working with Azure Digital Twin but only for the management plain, so I thought I'd try and write a small application which uses the Query API, but also handle the authentication flow. I've previously written a Fluent API for the Digital Twin Query API in C# and wanted to try something like it for Go using Generics. That's what this has become.

The authentication flow needs to read some values from environment variables. You can do this by either creating the environment variables, or by creating a .env file.

TWIN_URL=https://<twin instance>.<region>.digitaltwins.azure.net
TWIN_CLIENT_ID=<application id>
TWIN_CLIENT_SECRET=<client secret>
TWIN_TENANT_ID=<directory id>

Models / Ontology

The builder process uses models which implement the models.IModel interface. Each twin in Azure Digital Twin has a $dtId, $etag, and $metadata value, so there is a GenericModel type which can be inherited so that these items are handled for you. Each model needs to specify its model type so that its type can be validated if needed. An example model would look as follows.

package myontology

import (
	"azure-adt-example/digitaltwin/models"
)

type MyOntologyType struct {
	models.GenericModel
	Name           string `json:"name"`
}

func (MyOntologyType) Model() string {
	return "dtmi:digitaltwins:rec_3_3:agents:MyOntologyType;1"
}

func (MyOntologyType) Alias() string {
	return models.GetModelAlias[MyOntologyType]()
}

func (MyOntologyType) ValidationClause() string {
	return models.ModelValidationClause[MyOntologyType]()
}

The Alias and ValidationClause can be manually specified, but there are helper methods to generate the correct values. The GetModelAlias returns the name of the type in lowercase.

Usage

Once the models for the ontology have been specified the twin can be queried as follows.

config := azuread.NewTwinConfiguration()
// An authentication token can be provided, but if it isn't then the client will get it's own
client := digitaltwin.NewClient(config, nil)

from := rec33.Company{}

// Create a new builder using Company as the base twin type
builder := digitaltwin.NewBuilder(from, false)

var err error

// Add a join from Company to Building where the company "owns" the building
if err = builder.AddJoin(from, rec33.Building{}, "owns", false); err != nil {
    log.Fatal(err)
}

// Add a join to Level where it is part of the building
if err = builder.AddJoin(rec33.Building{}, rec33.Level{}, "isPartOf", true); err != nil {
    log.Fatal(err)
}

// Add a where clause for the query
if err = builder.WhereId(from, "<company id>"); err != nil {
    log.Fatal(err)
}

// Execute the generated query and return the company, building, and level objects from the results.
// There are also methods for a single return type and 2 return types
results, err := digitaltwin.ExecuteBuilder3[rec33.Company, rec33.Building, rec33.Level](client, builder)
if err != nil {
    log.Fatal(err)
}

// Output the names of the company, building, and level. Because of Generics the `TwinX` fields are
// typed and so access to all of the properties is available
for _, row := range results {
    fmt.Printf("%s is part of %s owned by %s\n", row.Twin3.Name, row.Twin2.Name, row.Twin1.Name)
}

Issues

This is a side project for teaching myself, but I'm putting it out there in case anyone else finds it useful.

There's still a number of things I want to implement.

  • Extend return types up to 5 types (5 is the maximum number of relationships in a query unless using MATCH which is still in preview)
  • Clean the interface up a bit to make it more obvious
  • Add where clause building which includes all the available functions from Digital Twin
  • UNIT TESTING

azure-adt-example's People

Contributors

dazfuller avatar

Stargazers

 avatar  avatar

Watchers

 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.