[英]Azure IoT Edge stop a module programmatically
我正在嘗試以編程方式更改 IoT Edge 模塊的“狀態”(運行或停止)和“restartPolicy”,以便停止模塊而不必重新創建設備的整個部署。
我已經看到 Edge Agent 的 Twin 在他的 desiredProperties 中有模塊的部署信息,我嘗試使用以下代碼(使用 Microsoft.Azure.Devices NuGet 包)修補它
public async Task ShutdownModule(string deviceId, string moduleId)
{
var twinEdgeAgent = await _registryManager.GetTwinAsync(deviceId, "$edgeAgent");
var patchJson = $"{{\"properties\":{{\"desired\":{{\"modules\":{{\"{moduleId}\":{{\"status\": \"stopped\", \"restartPolicy\": \"never\"}}}}}}}}}}";
await _registryManager.UpdateTwinAsync(deviceId, "$edgeAgent", patchJson, twinEdgeAgent.ETag);
}
不幸的是,這不起作用,我收到一個UnauthorizedException
消息“ErrorCode:SystemModuleModifyUnauthorizedAccess;Unauthorized to modify reserved module。”。 看起來我無法更改 Edge Agent 模塊的所需屬性。
有沒有辦法更改此屬性而不必重新創建整個部署 JSON,或者至少有沒有辦法獲取此部署 JSON,以便我可以修改需要更改的屬性?
我首先通過 EdgeAgent、EdgeHub 和所有模塊雙胞胎重建現有部署,通過部署 API 設法做到了這一點。
這是我最終編寫的方法的簡歷:
var modulesContent = new Dictionary<string, IDictionary<string, object>>();
var twinEdgeAgent = await _registryManager.GetTwinAsync(deviceId, "$edgeAgent");
var agentModules = twinEdgeAgent.Properties.Desired[ModulesJsonPropertyName];
agentModules[myModuleId]["status"] = "stopped";
agentModules[myModuleId]["restartPolicy"] = "never";
var desiredProperties = twinEdgeAgent.GetDesiredPropertiesDictionary();
modulesContent.Add("$edgeAgent", edgeHubDesiredProperties);
var twinEdgeHub = await _registryManager.GetTwinAsync(deviceId, "$edgeHub");
var edgeHubDesiredProperties = twinEdgeHub.GetDesiredPropertiesDictionary();
modulesContent.Add("$edgeHub", edgeHubDesiredProperties);
// foreach modules contained in agentModules also add
// the module's twin desired properties in the dictionary (not shown for brevity)
await _registryManager.ApplyConfigurationContentOnDeviceAsync(
deviceId,
new ConfigurationContent { ModulesContent = modulesContent });
internal static class TwinExtensions
{
private const string DesiredPropertiesAttribute = "properties.desired";
public static IDictionary<string, object> GetDesiredPropertiesDictionary(this Twin twin)
{
if (twin == null)
{
throw new ArgumentNullException(nameof(twin));
}
var twinDesiredProperties = twin.Properties.Desired;
twinDesiredProperties.ClearMetadata();
var twinDesiredPropertiesDictionary =
JsonConvert.DeserializeObject<Dictionary<string, object>>(twinDesiredProperties.ToJson());
return new Dictionary<string, object> {{DesiredPropertiesAttribute, twinDesiredPropertiesDictionary}};
}
}
也許有更好/更簡單的解決方案,但我們正在使用類似的方法來自動升級模塊的運行時映像和其他一些事情,因此我能夠在同一代碼中重新組合所有這些更改。
如果有一種方法可以直接獲取部署 JSON 但我沒有找到任何方法,那將會大大簡化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.