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 med att integrera Time Series Insights med Azure Digital Twins. Del 1 förklarar hur du upprättar en datapipeline som hämtar faktiska tidsseriedata från Azure Digital Twins till Time Series Insights , och den andra delen av självstudieserien förklarar synkronisering av tillgångsmodell mellan Azure Digital Twins och Time Series Insights. Den här självstudien beskriver metodtipsen för att välja och upprätta namngivningskonventioner för TS-ID (Time Series ID) och manuellt upprätta hierarkier i Time Series Model (TSM).

Välja ett Tidsserie-ID

Tidsserie-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ärdespar) 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 designen av TSM måste TSID:erna vara unika. Användning av tvilling-ID:t för tvillingarna i Azure Digital Twins eller kombinerat med egenskaps- eller telemetrinamn gör alltid unikt TS-ID i TSM. I ett typiskt fall <Twin ID> är TSID och egenskapen och telemetrinamnen är 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 modelleras som en tvilling och har tvilling-ID Room22. Dess temperaturinställningsegenskap ska översättas som TSID Room22_TempSetting och temperaturmätning som ska översättas till Room22_TempMea i TSM.

Choosing a Time Series ID

Kontextualisera tidsserier

Kontextualisering av data (främst 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 Explorer. Tidsserietyper och hierarkier definieras med time series-modellen (TSM) i Time Series Insights. Typer i TSM hjälper till att definiera variabler, medan hierarkinivåer och instansfältvärden används för att konstruera 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 relationerna mellan tillgångar hierarkiska. 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.

Connection between assets

Ö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 varje rum 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 startar från Building40 kan FlowMtr spåras via två olika sökvägar.

    1. Building40 -> Floor01 -> Room21 -> FlowMtr* -> Flow
    2. Building40 -> Floor01 -> Room22 -> FlowMtr* -> Flow
      Där "Flow" ä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 (överordnad-underordnad) relation

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:t enligt nedan. Instansfält kan uppdateras manuellt med Time Series Insights Explorer, men i avsnittet nedan med namnet "Uppdatera instansfält med API:er" beskrivs hur du lyssnar på modelländringar i Azure Digital Twins och uppdaterar instansfält i Time Series Insights med hjälp av Azure-funktioner.

Mapping twin IDs

Mapping twin IDs 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" precis under tvillingen "Room21". I framtiden när Time Series Insights kan stödja multirepresentation av tidsserier i TSM, skulle telemetrin "Flow" representeras under "Rum 21" och "Rum 22"

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

Mapping twin IDs in 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 aktuella exemplet, när du läser FlowMtr-telemetrin från IoT Hub och uppdaterar egenskapen "Flow" i FlowMtr-tvillingen, kan programmet även uppdatera motsvarande egenskaper i alla möjliga överordnade tvillingar till källan. I vårt exempel skulle det vara egenskapen "outflowmea" (identifieras med egenskapen "utflödesrelation" i Egenskapen Room21 och "inflowmea" i Room22. Nedan visas den slutliga användarupplevelsen i Time Series Insights-utforskaren. Det måste noteras att vi har datadbbletter genom att ta 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 i 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

Det här avsnittet i självstudien förklarar 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-funktioner. I Azure Digital Twins kan händelseaviseringar 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ändelseroutning och filtrering beskrivs här. Resten av det här avsnittet beskriver hur du använder Time Series Insights-modell-API:er i Azure-funktioner 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 för 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ågor i API:et.