Modellsynkronisering mellan Azure Digital Twins och Time Series Insights Gen2

Anteckning

Tjänsten Time Series Insights (TSI) stöds inte längre efter mars 2025. Överväg att migrera befintliga TSI-miljöer till alternativa lösningar så snart som möjligt. Mer information om utfasning och migrering finns i vår dokumentation.

Den här artikeln beskriver metodtips och verktyg som används för att översätta tillgångsmodellen i Azure Digital Twins (ADT) till tillgångsmodellen i Azure Time Series Insights (TSI). Den här artikeln är den andra delen i en självstudieserie i två delar som förklarar integreringen av Azure Digital Twins med Azure Time Series Insights. Integrering av Azure Digital Twins med Time Series Insights möjliggör arkivering och spårning av historiken för telemetrier och beräknade egenskaper för Digital Twins. Den här serien med självstudier riktar sig till utvecklare som arbetar för att integrera Time Series Insights med Azure Digital Twins. Del 1 beskriver hur du etablerar en datapipeline som hämtar in faktiska tidsseriedata från Azure Digital Twins till Time Series Insights . I den andra delen av självstudieserien förklaras synkronisering av tillgångsmodell mellan Azure Digital Twins och Time Series Insights. I den här självstudien beskrivs metodtipsen för att välja och upprätta namngivningskonventioner för Time Series ID (TS ID) och manuellt etablera hierarkier i Time Series Model (TSM).

Välja ett Tidsserie-ID

Time Series ID är en unik identifierare som används för att identifiera tillgångar i Time Series Insights. Tidsseriedata (telemetrier från fältet, som är tidsvärdepar) representeras med variabler som anges under TSID. I Azure Digital Twins används tvillingegenskaper och telemetrier för att representera tillståndet för en tvilling och mått som genereras av tvillingen. Från och med den aktuella utformningen av TSM måste TSID:erna vara unika. Om du använder tvilling-ID:t för tvillingarna i Azure Digital Twins eller kombineras med egenskaps- eller telemetrinamn blir det alltid unikt TS-ID i TSM. I ett typiskt fall <Twin ID> är TSID och egenskaps- och telemetrinamnen variablerna i TSM. Det finns dock användningsfall där det rekommenderas att tillgångshierarkier i Time Series Insights plattas ut med hjälp av formatet sammansatta nycklar, till exempel <Twin ID>+ <Delimiter of Choice> + <Name of the Property or Telemetry>. Låt oss ta ett exempel för att förklara det senare fallet. Överväg ett rum i en byggnad som är modellerad som en tvilling och har tvilling-ID Room22. Egenskapen för temperaturinställningen ska översättas som TSID-Room22_TempSetting och temperaturmätning som ska översättas till Room22_TempMea i TSM.

Välja ett Tidsserie-ID

Kontextualisera tidsserier

Kontextualisering av data (mestadels rumslig natur) i Time Series Insights uppnås via tillgångshierarkier och detsamma används för enkel navigering av data via en trädvy i Time Series Insights-utforskaren. Tidsserietyper och hierarkier definieras med hjälp av Time Series Model (TSM) i Time Series Insights. Typer i TSM hjälper till att definiera variabler, medan hierarkinivåer och fältvärden för instanser används för att skapa trädvyn i Time Series Insights-utforskaren. Mer information om TSM finns i dokumentationen om Time Series Insights online.

I Azure Digital Twins uttrycks anslutningen mellan tillgångar med hjälp av tvillingrelationer. Tvillingrelationer är helt enkelt ett diagram över anslutna tillgångar. Men i Time Series Insight är relationer mellan tillgångar hierarkiska till sin natur. Det innebär att tillgångar delar en överordnad-underordnad typ av relation och representeras med hjälp av en trädstruktur. För att översätta relationsinformation från Azure Digital Twins till Time Series Insights-hierarkier måste vi välja relevanta hierarkiska relationer från Azure Digital Twins. Azure Digital Twins använder ett öppet standardmodelleringsspråk som kallas DTDL (Digital Twin Definition Language). I DTDL-modeller beskrivs med en variant av JSON som kallas JSON-LD. Se DTDL-dokumentationen för fullständig information om specifikationen.

Anslutning mellan tillgångar

Översätta grafrepresentation i Azure Digital Twins till trädstruktur i Time Series Insights

Följande avsnitt i självstudien innehåller några grundläggande scenarier där du manuellt översätter grafstrukturen i Azure Digital Twins till trädstrukturen i Time Series Insights.

Exempelsystem: I den här självstudien används följande exempel för att förklara de begrepp som beskrivs nedan. Det är ett enkelt, fiktivt byggnadshanteringssystem med en våning och två rum. Den har tre termostater, en i vart och ett av rummen och en annan gemensam till golvet. Dessutom har den också en vattenflödesmätare som mäter vattenflödet från Room21 till Room22 genom en röranslutning mellan rummen. Om du tittar på den rumsliga relationen mellan tvillingar har den båda typerna av relationer.

  1. Den vanligaste hierarkiska relationen. Till exempel Building40 –> Floor01 –> FloorTS* –> Temperatur

  2. Inte så vanligt, cirkulärt förhållande. Om du till exempel börjar med Building40 kan FlowMtr spåras via två olika sökvägar.

    1. Byggnad 40 -> Floor01 -> Room21 -> FlowMtr* -> Flöde
    2. Byggnad 40 -> Floor01 -> Room22 -> FlowMtr* -> Flöde
      När "Flöde" är den faktiska telemetrin som mäter vattenflödet mellan Room21 och Room22

Anteckning

* FloorTS står för FloorThermoStat och FlowMtr står för Flow Meter och väljs vanligtvis som TSID. Temperatur och flöde är den råtelemetri som kallas variabler i Time Series Insights.

Med tanke på den aktuella begränsningen i Time Series Insights att en tillgång inte kan representeras i flera grenar förklarar följande avsnitt modellering av hierarkiska och cirkulära relationer i Time Series Insights.

Fall 1: Hierarkisk relation (överordnad-underordnad)

Det är den vanligaste typen av relation mellan tvillingarna. modellering av en ren överordnad-underordnad relation förklaras i följande bild. Instansfält och TSID härleds från tvilling-ID enligt nedan. Även om instansfält kan uppdateras manuellt med Time Series Insights-utforskaren, förklarar avsnittet nedan med namnet "Uppdatera instansfält med API:er" att lyssna på modelländringar i Azure Digital Twins och uppdatera instansfält i Time Series Insights med hjälp av Azure-funktioner.

Mappa tvilling-ID:t

Mappa tvilling-ID 2

Fall 2: Cirkulär relation

Cirkulär relation i Azure Digital Twins till en enda hierarkirelation i Time Series Insights

Eftersom TSID måste vara unikt och bara kan representeras i en hierarki representerar det här fallet "FlowMtr" med en telemetri med namnet "Flow" under tvillingen "Room21". I framtiden när Time Series Insights har stöd för flera representationer av tidsserier i TSM, representeras telemetrin "Flow" under "Rum 21" och "Rum 22"

Följande skärmbild visar hur du manuellt mappar tvilling-ID:t i fältet Azure Digital Twins till instans i TSM och den resulterande hierarkin i Time Series Insights.

Mappa tvilling-ID:t i Azure Digital Twins

Cirkulär relation i Azure Digital Twins till flera hierarkier i Time Series Insights med dubbletter

I del 1 av självstudien förklaras hur ett klientprogram (en Azure-funktion) hjälper till att överföra telemetridata från IoT Hub eller andra händelsekällor till Azure Digital Twins. Den här metoden föreslår att du använder samma klientprogram för att göra uppdateringar av relevanta egenskaper för de överordnade tvillingarna. I det här exemplet, när du läser FlowMtr-telemetrin från IoT Hub och uppdaterar egenskapen "Flow" i FlowMtr-tvillingen, kan programmet också uppdatera motsvarande egenskaper i alla möjliga överordnade tvillingar till källan. I vårt exempel skulle det vara egenskapen "outflowmea" (identifieras med hjälp av utflödesrelationen) för egenskapen Room21 och "inflowmea" för Room22. Skärmbilden nedan visar den slutliga användarupplevelsen i Time Series Insights-utforskaren. Det måste noteras att vi har datadbbletter genom att använda den här metoden.

Time Series Insights Explorer

Kodfragmentet nedan visar hur klientprogrammet kunde navigera i tvillingrelationen med hjälp av Azure Digital Twins-API:er.

Anteckning

Det här kodfragmentexemplet förutsätter att läsarna är bekanta med del 01 av självstudien och den här kodändringen gjordes i funktionen "ProcessHubToDTEvents".

if (propertyPath.Equals("/Flow"))
{
//Update the flow value property of the flow meter
await AdtUtilities.UpdateTwinProperty(client, twinId, "replace",
propertyPath, "double", propertyValue, log);

//also update the sending end flow
string parentIdOutflow = await AdtUtilities.FindParent(client, twinId,
"outflow", log);
if (parentIdOutflow != null)
await AdtUtilities.UpdateTwinProperty(client, parentIdOutflow, "replace", "outflow", "double", propertyValue, log);
else
log.LogInformation("Unable to find Parent with outflow
relationship for " + twinId );
//and receiving end flow value
string parentIdinflow = await AdtUtilities.FindParent(client, twinId,
"inflow", log);
if (parentIdinflow != null)

await AdtUtilities.UpdateTwinProperty(client, parentIdinflow,
"replace", "inflow", "double", propertyValue, log);
else
log.LogInformation("Unable to find Parent with inflow
relationship for " + twinId);
}

Uppdatera instansfält med API:er

I det här avsnittet av självstudien beskrivs hur du lyssnar på modelländringar i Azure Digital Twins, till exempel skapande, borttagning av tvillingar eller ändring i relationer mellan tvillingar och uppdatering av instansfält och hierarkier programmatiskt med hjälp av Time Series Insights-modell-API:er. Den här metoden för att uppdatera Time Series Insights-modellen uppnås vanligtvis via Azure Functions. I Azure Digital Twins kan händelsemeddelanden som tvillingtillägg eller borttagningar dirigeras nedströmstjänster, till exempel Event Hubs, som i sin tur kan matas till Azure-funktioner. Mer information om händelsedirigering och filtrering beskrivs här. Resten av det här avsnittet beskriver hur du använder Time Series Insights-modell-API:er i Azure Functions för att uppdatera Time Series Insights-modellen som svar på tvillingtillägg (en typ av modelländring) i Azure Digital Twins.

Ta emot och identifiera händelseavisering om tvillingtillägg

[FunctionName("RouteEventsToTsi")]
public async Task Run([EventGridTrigger]EventGridEvent eventGridEvent)
{
    try
    {
        if (eventGridEvent != null && eventGridEvent.Data != null)
        {
            logger.LogInformation($"EventType: {eventGridEvent.EventType}");
            logger.LogInformation($"EventGridEvent: {JsonConvert.SerializeObject(eventGridEvent)}");

            //Shape event and Send event data to event hub and tsi
            await SendEventToEventHubAsync(eventGridEvent).ConfigureAwait(false);

            //If a new twin was created, update the newly created instance in TSI with info retrieved from ADT
            if (eventGridEvent.EventType == Constants.TwinCreateEventType)
            {
                //retrieve building, floor and room of value twin
                var twinInfo = await RetrieveTwinInfoAsync(eventGridEvent).ConfigureAwait(false);
                //Update Tsi instance with type(sensor type), hierarchy(space hierarchy) and instance fields(twin info retrieved above)
                var instance = await CreateInstanceToSendAsync(twinInfo).ConfigureAwait(false);
                var instanceToUpdate = new List<TimeSeriesInstance>() { instance };
                var response = await tsiClient.TimeSeriesInstances.ExecuteBatchAsync(new InstancesBatchRequest(update: instanceToUpdate)).ConfigureAwait(false);
            }
        }
    }
    catch (Exception ex)
    {
        logger.LogError($"Exception: {ex.Message}");
    }
}

Skapa Time Series Insights-klienten och lägga till instansinformation

private async Task<TimeSeriesInstance> CreateInstanceToSendAsync(Dictionary<string, string> twinInfo)
{
    try
    {
        tsiClient = await GetTSIClientAsync().ConfigureAwait(false);

        var timeSeriesId = new object[] { twinInfo[Constants.DtId] };
        var instances = await tsiClient.TimeSeriesInstances.ExecuteBatchAsync(
            new InstancesBatchRequest(
                get: new InstancesRequestBatchGetOrDelete(
                    new IList<object>[] { timeSeriesId }))).ConfigureAwait(false);
        var instance = instances.Get.First().Instance;

        if (instance != null)
        {
            instance = await AddHierarchyToInstanceAsync(instance).ConfigureAwait(false);
            instance = await AddTypeToInstanceAsync(instance, twinInfo[Constants.TwinType]).ConfigureAwait(false);

            instance.InstanceFields = new Dictionary<string, object>
                            {
                                { "Building", twinInfo[Constants.BuildingName] },
                                { "Floor", twinInfo[Constants.FloorName] },
                                { "Room", twinInfo[Constants.ParentName] }
                            };

            //If value twin is a sensor value twin, add sensor type instance field to diff from spatial value twin
            if (twinInfo[Constants.ParentType] == Constants.Sensor)
            {
                instance.InstanceFields.Add(Constants.SensorType, twinInfo[Constants.TwinType]);
            }
            return instance;
        }
        else
        {
            logger.LogError($"instance with id {twinInfo[Constants.DtId]} not found");
            return new TimeSeriesInstance();
        }
    }
    catch (Exception e)
    {
        logger.LogError(e.Message);
        throw;
    }
}

Tillämpa hierarkiinformation på instans

private async Task<TimeSeriesInstance> AddHierarchyToInstanceAsync(TimeSeriesInstance instance)
{
    if (instance.HierarchyIds == null)
    {
        TimeSeriesHierarchy spacesHierarchy = null;
        try
        {
            var hierarchy = await RunGetHierarchiesAsync(Constants.SpaceHierarchy).ConfigureAwait(false);
            spacesHierarchy = hierarchy.First(h => h.Name.Equals(Constants.SpaceHierarchy));
            instance.HierarchyIds = new List<Guid?>();
            instance.HierarchyIds.Add(spacesHierarchy.Id);
        }
        catch (Exception ex)
        {
            logger.LogWarning($"Hierarchy 'space hierarchy' not found, {ex}");
            throw;
        }
    }
    return instance;
}

Nästa steg

Det tredje i serien med självstudier är att visa hur du frågar efter historiska data från Azure Digital Twins med hjälp av Time Series Insights-API:er. Det är ett pågående arbete och avsnittet uppdateras när det är klart. Under tiden uppmanas läsarna att läsa dokumentationen för Time Series Insights-datafråge-API:et.