你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
管理 Azure 数字孪生模型
本文介绍如何管理 Azure 数字孪生实例中的模型。 管理操作包括上传、验证、检索和删除模型。
先决条件
若要在本文中使用 Azure 数字孪生,你需要有一个 Azure 数字孪生实例,还需具备使用它所必需的权限。 如果你已设置了一个 Azure 数字孪生实例,则可以使用该实例并跳到下一部分。 如果没有,请按照设置实例和身份验证中的说明操作。 该说明中包含可帮助你验证是否已成功完成每个步骤的信息。
设置实例后,记下实例的主机名。 可以在 Azure 门户中找到该主机名。
开发人员接口
本文重点介绍如何使用 .NET (C#) SDK 完成不同的管理操作。 还可使用 Azure 数字孪生 API 和 SDK 中所述的其他语言 SDK 创建这些管理调用。
其他可用于完成这些操作的开发人员接口包括:
注意
当前,Azure Digital Twins Explorer 完全支持 DTDL v2 模型,并支持 DTDL v3 模型的有限功能。
可以在“模型”面板中查看 DTDL v3 模型,并且可以查看和编辑使用 DTDL v3 模型创建的孪生体(包括具有数组属性的孪生体)。 但是,DTDL v3 模型不会显示在“模型图”面板中,也无法使用 Azure Digital Twins Explorer 导入。 要将 DTDL v3 模型导入实例,请使用另一个开发人员接口,例如 API 和 SDK 或 Azure CLI。
可视化效果
Azure Digital Twins Explorer 是一种可视化工具,用于浏览 Azure 数字孪生图中的数据。 你可以使用此资源管理器查看、查询和编辑模型、孪生和关系。
若要了解 Azure Digital Twins Explorer 工具,请参阅 Azure Digital Twins Explorer。 如需各项功能的详细使用步骤,请参阅使用 Azure Digital Twins Explorer。
下面展示了可视化效果:
创建模型
你可以从头开始创建自己的模型,或使用所在行业可用的现有本体。
作者模式
Azure 数字孪生的模型用 DTDL 编写,并保存为 .json 文件。 还有一个可用于 Visual Studio Code 的 DTDL 扩展,该扩展提供语法验证和便于编写 DTDL 文档的其他功能。
假设一家医院希望以数字方式表示房间。 每个房间都包含一个用于监视洗手情况的智能给皂器,以及用于监视房间人流量的传感器。
解决方案的第一步是创建模型来表示医院的各个方面。 此方案中的病房可以这样描述:
{
"@id": "dtmi:com:contoso:PatientRoom;1",
"@type": "Interface",
"@context": "dtmi:dtdl:context;3",
"displayName": "Patient Room",
"contents": [
{
"@type": "Property",
"name": "visitorCount",
"schema": "double"
},
{
"@type": "Property",
"name": "handWashCount",
"schema": "double"
},
{
"@type": "Property",
"name": "handWashPercentage",
"schema": "double"
},
{
"@type": "Relationship",
"name": "hasDevices"
}
]
}
注意
这是一个 JSON 文件的示例正文,其中定义并保存了模型,并且该模型将作为客户端项目的一部分上传。 另一方面,REST API 调用采用类似于上面的模型定义数组(该数组在 .NET SDK 中映射到 IEnumerable<string>
)。 因此,若要直接在 REST API 中使用此模型,请用括号括起来。
此模型定义了病房的名称和唯一 ID,并定义了表示访客人数和洗手状态的属性。 这些计数器将根据运动传感器和智能给皂器进行更新,并将一起用于计算 handwash percentage
属性。 该模型还定义了一个关系 hasDevices
,用于将基于此 Room 模型的任何数字孪生体连接到实际设备。
注意
Azure 数字孪生目前不支持某些 DTDL 功能,包括属性和关系的 writable
属性,以及关系的 minMultiplicity
和 maxMultiplicity
。 有关详细信息,请参阅特定于服务的 DTDL 说明。
按照此方法,可为医院的病房、区域或医院本身定义模型。
如果你的目标是构建一个描述行业域的综合模型集,请考虑是否有现成的行业本体可用来更轻松地创建模型。 下一部分更详细地介绍了行业本体。
使用现有的行业标准本体
本体学是一组模型,用于全面描述给定领域,例如制造、建筑结构、IoT 系统、智能城市、能源网格、Web 内容等。
如果解决方案适用于使用任何类型的建模标准的特定行业,请考虑从为行业设计的预先存在的模型集开始,而不是从头开始设计模型。 Microsoft 与领域专家合作,根据行业标准创建 DTDL 模型本体,以帮助最大程度地减少重塑并鼓励跨行业解决方案的一致性和简单性。 有关这些本体的详细信息(包括如何使用本体以及现在提供哪些本体),可参阅什么是本体?。
验证语法
创建模型后,建议先离线对其进行验证,然后再将其上传到 Azure 数字孪生实例。
为了帮助你验证模型,NuGet 上提供了一个 .NET 客户端 DTDL 分析库:DTDLParser。 可以直接在 C# 代码中使用分析器库。 还可以在 GitHub 的 DTDLParserResolveSample 中查看分析器的示例用法。
上传模型
创建模型后,可将它们上传到 Azure 数字孪生实例。
准备好上传模型后,可对 .NET SDK 使用以下代码片段:
// 'client' is an instance of DigitalTwinsClient
// Read model file into string (not part of SDK)
// fileName is the name of the JSON model file
string dtdl = File.ReadAllText(fileName);
await client.CreateModelsAsync(new[] { dtdl });
上传时,模型文件由服务进行验证。
通常需要将多个模型上传到服务。 可通过多种方式在单次事务中一次性上传多个模型。 为了帮助你选取策略,请考虑在继续学习本部分的其余部分时设置的模型集大小。
上传小型模型集
对于较小的模型集,可以使用单个 API 调用一次性上传多个模型。 可以在 Azure 数字孪生限制的单个 API 调用中检查可以上传的模型数的当前限制。
如果使用的是 SDK,则可以使用 CreateModels
方法上传多个模型文件,如下所示:
var dtdlFiles = Directory.EnumerateFiles(sourceDirectory, "*.json");
var dtdlModels = new List<string>();
foreach (string fileName in dtdlFiles)
{
// Read model file into string (not part of SDK)
string dtdl = File.ReadAllText(fileName);
dtdlModels.Add(dtdl);
}
await client.CreateModelsAsync(dtdlModels);
如果使用的是 REST API 或 Azure CLI,可以将要一起上传的多个模型定义放在单个 JSON 文件中来上传多个模型。 在这种情况下,模型应放置在该文件内的一个 JSON 数组中,如以下示例所示:
[
{
"@id": "dtmi:com:contoso:Planet;1",
"@type": "Interface",
"@context": "dtmi:dtdl:context;3"
},
{
"@id": "dtmi:com:contoso:Moon;1",
"@type": "Interface",
"@context": "dtmi:dtdl:context;3"
}
]
使用导入作业 API 上传大型模型集
对于大型模型集,可以使用导入作业 API 在单个 API 调用中一次性上传多个模型。 API 可以同时接受实例中 Azure 数字孪生对于模型数的限制,并根据需要自动对模型重新排序以解析它们之间的依赖项。 此方法要求在 Azure 数字孪生实例中为模型和批量作业使用 Azure Blob 存储和写入权限。
提示
导入作业 API 还允许在同一调用中导入孪生体和关系,以便同时创建图形的所有部分。 有关此过程的详细信息,请参阅使用导入作业 API 批量上传模型、孪生体和关系。
若要批量导入模型,需要将模型(以及批量导入作业中包含的任何其他资源)构建为 NDJSON 文件。 Models
节紧接在 Header
节之后,使其成为文件中的第一个图形数据部分。 可以在导入作业 API 简介中查看用于创建这些文件的示例导入文件和示例项目。
接下来,需要将文件上传到 Azure Blob 存储中的追加 blob 中。 若要了解如何创建 Azure 存储容器,请参阅创建容器。 然后,使用首选上传方法(一些选项包括 AzCopy 命令、Azure CLI 或 Azure 门户)上传文件。
将 NDJSON 文件上传到容器后,在 blob 容器中获取其 URL。 稍后将在批量导入 API 调用正文中使用此值。
下面是显示 Azure 门户中 Blob 文件的 URL 值的屏幕截图:
然后,可以在导入作业 API 调用中使用该文件。 你将提供输入文件的 Blob 存储 URL,以及新的 Blob 存储 URL,以指示在服务创建输出日志时,希望将它存储在什么位置。
检索模型
可列出和检索存储在 Azure 数字孪生实例上的模型。
您的选择包括:
- 检索单个模型
- 检索所有模型
- 检索模型的元数据和依赖项
下面是一些示例调用:
// 'client' is a valid DigitalTwinsClient object
// Get a single model, metadata and data
Response<DigitalTwinsModelData> md1 = await client.GetModelAsync("<model-Id>");
DigitalTwinsModelData model1 = md1.Value;
// Get a list of the metadata of all available models; print their IDs
AsyncPageable<DigitalTwinsModelData> md2 = client.GetModelsAsync();
await foreach (DigitalTwinsModelData md in md2)
{
Console.WriteLine($"Type ID: {md.Id}");
}
// Get models and metadata for a model ID, including all dependencies (models that it inherits from, components it references)
AsyncPageable<DigitalTwinsModelData> md3 = client.GetModelsAsync(new GetModelsOptions { IncludeModelDefinition = true });
用于检索模型的 SDK 调用全都返回 DigitalTwinsModelData
对象。 DigitalTwinsModelData
包含有关存储在 Azure 数字孪生实例中的模型的元数据,例如模型的名称、DTMI 和创建日期。 DigitalTwinsModelData
对象也可以选择包含模型本身。 这意味着,根据参数,可以使用检索调用仅检索元数据(在希望显示可用工具的 UI 列表等情况下,这很有用),也可以检索整个模型。
RetrieveModelWithDependencies
调用不仅返回所请求的模型,还返回请求的模型所依赖的所有模型。
模型不一定完全按照上传时的文档形式返回。 Azure 数字孪生仅保证返回的形式在语义上是等效的。
更新模型
本节介绍更新模型的注意事项和策略。
更新前:考虑整个解决方案的上下文
在更新模型之前,建议从整体上考虑整个解决方案以及即将进行的模型更改的影响。 Azure 数字孪生解决方案中的模型通常是互连的,因此,必须注意级联更改,其中更新一个模型需要更新其他多个模型。 更新模型会影响使用模型的孪生体,还可能会影响流入量和处理代码、客户端应用程序和自动化报表。
下面是有助于顺利管理模型转换的一些建议:
- 请考虑在适当的时候改进整个模型集,使模型及其关系一起保持最新,而不是将模型视为单独的实体。
- 将模型视为源代码,在源代码管理中管理它们。 对模型和模型更改应用与解决方案中应用于其他代码相同的严格性和关注。
如果已准备好继续执行更新模型的过程,请参阅本节的其余部分以了解可用于实现更新的策略。
更新模型的策略
模型上传到 Azure 数字孪生实例后,模型界面不可变,这意味着没有传统的模型“编辑”。 实例中已存在匹配的模型时,Azure 数字孪生也不允许重新上传完全相同的模型。
但如果要更改模型(例如更新 displayName
或 description
,或者添加和删除属性),则需要替换原始模型。
替换模型时,有两种策略可供选择:
- 策略 1:上传新模型版本:上传具有新版本号的模型,并更新孪生体以使用该新模型。 新模型版本和旧模型版本的将同时存在于实例中,直至删除其中一个。
- 如果只想更新使用该模型的一些孪生体,或者希望确保孪生体符合其模型并可通过模型转换进行写入,请使用此策略。
- 策略 2:删除旧模型并重新上传:删除原始模型,并上传具有相同名称和 ID 的新模型(DTMI 值)替换。 使用新模型完全替换旧模型。
- 如果想一次更新使用此模型的所有孪生体,以及所有对模型做出反应的代码,请使用此策略。 如果模型更新包含对模型更新的中断性变更,则孪生体在从旧模型转换到新模型时,会在短时间内不符合它们的模型,这意味着在上传新模型并且孪生体符合新模型之前,它们将无法执行任何更新。
注意
在开发之外,不鼓励对模型进行中断性变更。
继续看以下几节,详细阅读每个策略选项的更多信息。
策略 1:上传新模型版本
此选项涉及创建新模型版本并将其上传到实例。
此操作不会覆盖模板的早期版本,因此在删除早期版本之前,实例中会同时存在多个模型版本。 由于新模型版本和旧模型版本共存,因此孪生体可以使用新模型版本,也可以使用旧模型版本,这意味着上传新模型版本不会自动影响现有孪生体。 现有孪生体将保留为旧模型版本的实例,可以通过修补这些孪生体将其更新为新模型版本。
若要使用此策略,请执行以下步骤。
1. 创建并上传新模型版本
若要创建现有模型的新版本,请从原始模型的 DTDL 开始。 更新、添加或删除要更改的字段。
接下来,更新此模型的 id
字段,将模型标记为新模型版本。 模型 ID 的最后一个部分(;
后面的部分)表示模型编号。 若要指示此模型目前是最新版本,请将 id
值末尾的数字递增为大于当前版本号的任意数字。
例如,如果之前的模型 ID 如下所示:
"@id": "dtmi:com:contoso:PatientRoom;1",
此模型的版本 2 可能如下所示:
"@id": "dtmi:com:contoso:PatientRoom;2",
然后,将新模型版本上传到实例。
此版本的模型随后将在实例中提供,用于数字孪生体。 它不会覆盖早期模型版本,因此模型的多个版本此时在实例中共存。
2. 根据需要更新图元素
接下来,更新实例中的“孪生体和关系”,以使用新模型版本,而不再使用旧模型版本。
可以使用以下说明更新孪生体和更新关系。 更新孪生体模型的修补操作如下所示:
[
{
"op": "replace",
"path": "/$metadata/$model",
"value": "dtmi:example:foo;1"
}
]
重要
更新孪生体时,使用“同一补丁”来同时更新模型 ID(更新为新模型版本)和孪生体上必须更改的任何字段以使其符合新模型。
可能还需要更新实例中引用此模型的“关系”和其他“模型”,使其引用新模型版本。 需要执行另一个模型更新操作来实现此目的,因此请返回到本节的开头,并针对需要更新的其他任何模型重复此过程。
3. (可选)停用或删除旧模型版本
如果不再使用旧模型版本,可以停用旧模型。 此操作允许模型保留在实例中,但不能用于创建新的数字孪生体。
如果不想再在实例中使用旧模型,也可以将其完全删除。
上面链接的几节包含有关停用和删除模型的示例代码和注意事项。
策略 2:删除旧模型并重新上传
可以完全删除模型,并将编辑后的模型重新上传到实例,而不是递增模型的版本。
Azure 数字孪生不记得旧模型曾经上传过,因此此操作就像上传全新的模型一样。 使用该模型的孪生体在可用后会自动切换到新定义。 根据新定义与旧定义的区别,这些孪生体的属性和关系可能与已删除的定义相匹配,并且对于新定义无效,因此可能需要修补它们以确保其保持有效。
若要使用此策略,请执行以下步骤。
1. 删除旧模型
由于Azure 数字孪生不允许两个模型具有相同的 ID,因此首先从实例中删除原始模型。
注意
如果有其他模型依赖于此模型(通过继承或组件),则需要先删除这些引用,然后才能删除该模型。 可以先更新这些依赖的模型以暂时删除引用,或删除依赖的模型并在后面的步骤中重新上传。
使用以下说明删除原始模型。 此操作会暂时将使用该模型的孪生体“孤立”,因为它们现在使用的是不再存在的模型。 此状态将在下一步重新上传更新的模型时修复。
2. 创建并上传新模型
从原始模型的 DTDL 开始。 更新、添加或删除要更改的字段。
然后,上传模型到实例,就像它是首次上传的新模型一样。
3. 根据需要更新图元素
现在,新模型已上传并替换旧模型,一旦实例中的高速缓存过期并重置,图中的孪生体将自动开始使用新模型定义。 此过程可能需要 10-15 分钟或更长时间,具体取决于图的大小。 之后,应可访问模型的新属性和已更改的属性,而已删除的属性将不再可访问。
注意
如果之前为了删除原始模型而删除了其他依赖的模型,现在请在缓存重置后将其重新上传。 如果更新了依赖的模型以暂时删除对原始模型的引用,可以再次更新它们以放回引用。
接下来,更新实例中的“孪生体和关系”,以便其属性与新模型定义的属性匹配。 在此步骤完成之前,仍可以读取与模型不匹配的孪生体,但不能写入。 有关没有有效模型的孪生体状态的详细信息,请参阅无模型的孪生体。
有两种方法可以针对新模型更新孪生体和关系,以使其再次可写:
- 根据需要修补孪生体和关系,以使其适合新模型。 可以使用以下说明更新孪生体和更新关系。
- 如果已添加属性:不需要更新孪生体和关系以具有新值,因为缺少新值的孪生体仍将是有效的孪生体。 但如果想要针对新属性添加值,可以修补它们。
- 如果已删除属性:需要修补孪生体以删除现在对于新模型无效的属性。
- 如果已更新属性:需要修补孪生体,以更新已更改属性的值,使其对于新模型有效。
- 删除使用模型的孪生体和关系,然后重新创建它们。 可以使用以下说明来删除孪生体并重新创建孪生体,以及删除关系并重新创建关系。
- 如果要对模型进行许多更改,可能需要执行此操作,很难更新现有孪生体来匹配它。 但是,如果有许多孪生体由许多关系互连,则重新创建会很复杂。
删除模型
可通过以下两种方式之一从服务中删除模型:
- 解除分配:解除分配某个模型后,不再可以使用它来创建新的数字孪生。 已使用此模型的现有数字孪生体不会受到影响,因此你仍可通过属性更改、添加或删除关系等操作对孪生体进行更新。
- 删除:此操作将从解决方案中完全删除该模型。 使用此模型的任何孪生体不再与任何有效模型关联,因此它们被视为根本没有模型。 用户仍可读取这些孪生体,但在将它们重新分配到另一个模型之前,不能对它们进行任何更新。
这些操作是独立的功能,尽管它们可以一起使用来逐步删除模型,但它们不会相互影响。
注意
如果要一次性删除实例中的所有模型、孪生体和关系,请使用删除作业 API。
停止使用
若要停用一个模型,可以使用 SDK 中的 DecommissionModel 方法:
// 'client' is a valid DigitalTwinsClient
await client.DecommissionModelAsync(dtmiOfPlanetInterface);
// Write some code that deletes or transitions digital twins
//...
还可使用 REST API 调用 DigitalTwinModels Update 来停用模型。 decommissioned
属性是唯一可以替换为此 API 调用的属性。 JSON 补丁文档将如下所示:
[
{
"op": "replace",
"path": "/decommissioned",
"value": true
}
]
模型的停止使用状态包含在模型检索 API 返回的 ModelData
记录中。
删除
可一次删除实例中的所有模型,也可逐个删除。
有关如何同时删除所有模型的示例,请参阅 Azure 数字孪生端到端示例 GitHub 存储库。 “CommandLoop.cs”文件包含 CommandDeleteAllModels
函数,具有用于删除实例中所有模型的代码。
若要删除单个模型,请按照本节其余内容中的说明和注意事项进行操作。
删除前:删除的要求
通常,可随时删除模型。
但有一个例外情况,如果有其他模型依赖该模型(无论是通过 extends
关系还是以组件形式),则该模型不可删除。 例如,如果 ConferenceRoom 模型扩展了 Room 模型,并拥有组件形式的 ACUnit 模型,则在 ConferenceRoom 删除这些相应引用之前,不能删除 Room 或 ACUnit。
若要删除被依赖的模型,可以更新依赖的模型以删除依赖项,或者完全删除依赖的模型。
删除期间:删除过程
即使模型满足立即删除的要求,你也可能需要先执行几个步骤,以避免留下的孪生体出现意外后果。 下面是可帮助你管理该过程的一些步骤:
- 首先,停止使用该模型
- 等待几分钟,确保服务已处理完最后发送的孪生体创建请求再停止使用
- 按模型查询孪生体,查看正在使用现已停用的模型的所有孪生体
- 如果不再需要这些孪生体,请将它们删除,或根据需要将它们修补为新模型。 还可选择不管它们,在这种情况下,在删除该模型后,这些模型就会变为无模型的孪生体。 有关此状态的含义,请参阅下一节。
- 等待几分钟,确保更改已完成
- 删除模型
若要删除模型,可以使用 DeleteModel SDK 调用:
// 'client' is a valid DigitalTwinsClient
await client.DeleteModelAsync(IDToDelete);
还可使用 DigitalTwinModels Delete REST API 调用删除模型。
删除后:无模型的孪生体
删除某一模型后,使用该模型的任何数字孪生体现在都被视为无模型。 没有任何查询可提供此状态的所有孪生体的列表,但仍可通过已删除的模型来查询孪生体,以了解哪些孪生体受到影响。
下面概述了无模型孪生体可执行和不可执行的操作。
可执行的操作:
- 查询孪生体
- 读取属性
- 读取传出关系
- 添加和删除传入关系(例如,其他孪生体仍可与此孪生体建立关系)
- 关系定义中的
target
仍可反映已删除模型的 DTMI。 未定义目标的关系在此处也适用。
- 关系定义中的
- 删除关系
- 删除孪生体
不可执行的操作:
- 编辑传出关系(例如,此孪生体与其他孪生体建立的关系)
- 编辑属性
删除后:重新上传模型
删除某一模型后,可决定稍后上传与删除的模型具有相同 ID 的新模型。 下面是在这种情况下会发生的事项。
- 从解决方案商店的角度来看,此操作等同于上传一个全新的模型。 该服务不记得这个旧模型曾经上传过。
- 如果图中有任何引用已删除模型的剩余孪生体,则它们将不再是孤立的;此模型 ID 对于新定义仍然有效。 但是,如果模型的新定义不同于已删除的模型定义,则这些孪生体的属性和关系可能与已删除的定义相匹配,并且对于新定义无效。
Azure 数字孪生不会阻止此状态,因此请小心适当地修补孪生体,以确保它们通过模型定义切换后仍然有效。
将 v2 模型转换为 v3
Azure 数字孪生支持 DTDL 版本 2 和 3(在本文档中分别简写为 v2 和 v3)。 基于 V3 扩展的功能,建议选择 V3。 本部分介绍如何将现有 DTDL v2 模型更新为 DTDL v3。
- 更新上下文。 标识模型是 v2 还是 v3 的主要功能是接口上的“
@context
”字段。 若要将模型从 v2 转换为 v3,请将dtmi:dtdl:context;2
上下文值更改为dtmi:dtdl:context;3
。 对于许多模型,这是唯一必需的更改。- v2 中的值:
"@context": "dtmi:dtdl:context;2"
- v3 中的值:
"@context": "dtmi:dtdl:context;3"
。
- v2 中的值:
- 如有需要,请更新语义类型。 在 DTDL v2 中,本机支持语义类型。 在 DTDL v3 中,它们包含在 QuantitativeTypes 功能扩展中。 因此,如果 v2 模型使用了语义类型,则需要在将模型转换为 v3 时添加功能扩展。 为此,请先将接口上的
@context
字段从单个值更改为值数组,然后添加值dtmi:dtdl:extension:quantitativeTypes;1
。- v2 中的值:
"@context": "dtmi:dtdl:context;2"
- v3 中的值:
"@context": ["dtmi:dtdl:context;3", "dtmi:dtdl:extension:quantitativeTypes;1"]
- v2 中的值:
- 如有需要,请考虑大小限制。 V2 和 v3 的大小限制不同,因此,如果接口非常大,可能需要在“DTDL v2 和 v3 之间的差异”中查看限制。
完成这些更改后,以前的 DTDL v2 模型已转换为 DTDL v3 模型。
你可能还想考虑 DTDL v3 的新功能,例如数组类型属性、版本放松和其他功能扩展,看看其中是否有任何功能是有益的补充。 有关 DTDL v2 和 v3 之间的差异的完整列表,请参阅 DTDL v3 语言说明中的版本 2 的更改。
注意
当前,Azure Digital Twins Explorer 完全支持 DTDL v2 模型,并支持 DTDL v3 模型的有限功能。
可以在“模型”面板中查看 DTDL v3 模型,并且可以查看和编辑使用 DTDL v3 模型创建的孪生体(包括具有数组属性的孪生体)。 但是,DTDL v3 模型不会显示在“模型图”面板中,也无法使用 Azure Digital Twins Explorer 导入。 要将 DTDL v3 模型导入实例,请使用另一个开发人员接口,例如 API 和 SDK 或 Azure CLI。
后续步骤
请参阅如何基于模型创建和管理数字孪生体: