Модули в следующих уроках будут c приличным количеством параметров и развертывать их руками через Web интерфейс Azure хоть и полезно вначале для понимания сути процесса, но не практично с т.з. временных затрат. Поэтому остановлюсь подробнее на настройке файла deployment.template.json. В документации Microsoft об этом сказано немало, поэтому в данном случае лишь акцентирую на этом внимание, если упустили из виду.
Создание deployment.template.json
Наверняка вы уже обратили внимание, что при создании модуля «с чистого листа» в Visual Studio Code в файле deployment.template.json присутствует описание тестового модуля термодатчика. В большинстве случаев он не нужен и используется для целей проверки работоспособности создаваемых модулей. Нужно не забывать убирать его из .json файла руками, чтобы не огрести лишний (не бесплатный) трафик в IoT Hub.
При создании нового проекта файл deployment.template.json содержит достаточно полей для развертывания, нужно лишь их немного подправить, адаптировав для своих нужд. Поэтому на полях, которые штатно уже присутствуют в deployment.template.json останавливаться не буду.
В предыдущем уроке properties.desired для модуля modbus довольно масштабный.
"properties.desired": { "PublishInterval": "2000", "SlaveConfigs": { "TermoSensor": { "SlaveConnection": "192.168.26.110", "HwId": "TermoSensor-0a:01:01:01:01:01", "TcpPort": "8899", "Operations": { "Op01": { "PollingInterval": "5000", "UnitId": "1", "StartAddress": "30002", "Count": "1", "DisplayName": "Temp" }, "Op02": { "PollingInterval": "5000", "UnitId": "1", "StartAddress": "30003", "Count": "1", "DisplayName": "Humidity" } } } } }
Если нправить Module Identity Twin вручную — это отнимет немало времени. Это особенно важно, если при разработке используется триальный аккаунт Azure и периодически приходится создавать новый аккаунт для завершения обучения/разработки. Развертывание должно быть максимально автоматизировано, чтобы не тратить время на воссоздание рабочей среды.
Посмотрим файл deployment.template.json из исходников модуля modbus:
{ "moduleContent": { "$edgeAgent": { "properties.desired": { "schemaVersion": "1.0", "runtime": { "type": "docker", "settings": { "minDockerVersion": "v1.25", "loggingOptions": "", "registryCredentials": { "warlibregistry": { "username": "$CONTAINER_REGISTRY_USERNAME_warlibregistry", "password": "$CONTAINER_REGISTRY_PASSWORD_warlibregistry", "address": "warlibregistry.azurecr.io" } } } }, "systemModules": { "edgeAgent": { "type": "docker", "settings": { "image": "mcr.microsoft.com/azureiotedge-agent:1.0", "createOptions": "" } }, "edgeHub": { "type": "docker", "status": "running", "restartPolicy": "always", "settings": { "image": "mcr.microsoft.com/azureiotedge-hub:1.0", "createOptions": "" } } }, "modules": { "modbus": { "version": "1.0", "type": "docker", "status": "running", "restartPolicy": "always", "settings": { "image": "${MODULES.iotedgeModbus.amd64}", "createOptions": "" } } } } }, "$edgeHub": { "properties.desired": { "schemaVersion": "1.0", "routes": { "iotedgeModbusToIoTHub": "FROM /messages/modules/modbus/outputs/modbusOutput INTO $upstream" }, "storeAndForwardConfiguration": { "timeToLiveSecs": 7200 } } }, "modbus": { "properties.desired":{ "PublishInterval": "5000", "SlaveConfigs": { "Slave01": { "SlaveConnection": "<IPV4 address>", "TcpPort": "502", "RetryCount": "10", "RetryInterval": "100", "HwId": "PowerMeter-0a:01:01:01:01:01", "Operations": { "Op01": { "PollingInterval": "2000", "UnitId": "1", "StartAddress": "400001", "Count": "2", "CorrelationId": "MessageType1", "DisplayName": "Voltage" }, "Op02": { "PollingInterval": "2000", "UnitId": "1", "StartAddress": "400002", "Count": "2", "CorrelationId": "MessageType2", "DisplayName": "Current" } } }, "Slave02": { "SlaveConnection": "<SerialPortName>", "RetryCount": "10", "RetryInterval": "50", "HwId": "PowerMeter-0a:01:01:01:01:02", "BaudRate": "9600", "DataBits": "8", "StopBits": "1", "Parity": "ODD", "FlowControl": "NONE", "Operations": { "Op01": { "PollingInterval": "2000", "UnitId": "1", "StartAddress": "40001", "Count": "2", "DisplayName": "Voltage" }, "Op02": { "PollingInterval": "2000", "UnitId": "1", "StartAddress": "40002", "Count": "2", "DisplayName": "Current" } } } } } } } }
Обратим внимание на секции JSON properties.desired для «$edgeHub» и «modbus»:
"modbus": { "properties.desired":{ ... } }
В эти секции заносятся все параметры properties.desired, которые по умолчанию должны присутствовать для модуля и правятся в дальнейшем через Module Identity Twin в web интерфейсе Azure Portal. Сразу отмечу, что properties.desired «$edgeHub» поправить через Module Identity Twin после создания нельзя. Поэтому нужно очень внимательно отнестись к настройке маршрутизации. Ошибка модет привести к тому, что придется удалять устройство (модули удалить на данный момент нельзя) и пересоздавать заново. Например, в случае с термодатчиком файл deployment.template.json модуля modbus будет выглядеть так:
{ "moduleContent": { "$edgeAgent": { "properties.desired": { "schemaVersion": "1.0", "runtime": { "type": "docker", "settings": { "minDockerVersion": "v1.25", "loggingOptions": "", "registryCredentials": { "warlibregistry": { "username": "$CONTAINER_REGISTRY_USERNAME_warlibregistry", "password": "$CONTAINER_REGISTRY_PASSWORD_warlibregistry", "address": "warlibregistry.azurecr.io" } } } }, "systemModules": { "edgeAgent": { "type": "docker", "settings": { "image": "mcr.microsoft.com/azureiotedge-agent:1.0", "createOptions": "" } }, "edgeHub": { "type": "docker", "status": "running", "restartPolicy": "always", "settings": { "image": "mcr.microsoft.com/azureiotedge-hub:1.0", "createOptions": "" } } }, "modules": { "modbus": { "version": "1.0", "type": "docker", "status": "running", "restartPolicy": "always", "settings": { "image": "${MODULES.iotedgeModbus.amd64}", "createOptions": "" } } } } }, "$edgeHub": { "properties.desired": { "schemaVersion": "1.0", "routes": { "iotedgeModbusToIoTHub": "FROM /messages/modules/modbus/outputs/modbusOutput INTO $upstream" }, "storeAndForwardConfiguration": { "timeToLiveSecs": 7200 } } }, "modbus": { "properties.desired": { "PublishInterval": "2000", "SlaveConfigs": { "TermoSensor": { "SlaveConnection": "192.168.26.110", "HwId": "TermoSensor-0a:01:01:01:01:01", "TcpPort": "8899", "Operations": { "Op01": { "PollingInterval": "5000", "UnitId": "1", "StartAddress": "30002", "Count": "1", "DisplayName": "Temp" }, "Op02": { "PollingInterval": "5000", "UnitId": "1", "StartAddress": "30003", "Count": "1", "DisplayName": "Humidity" } } } } } } } }
В файле описаны все параметры, которые нужно вводить руками при создании модуля через Azure portal: маршрутизация и properties.desired.
Развертывание deployment.json
Файл для ращвертывания подготовлен, напомню последовательность сборки и развертывания модуля:
- В Visual Studio Code встаем на файд deployment.template.json.
- Жмем правую кнопку мыши.
- Выбираем пункт «Build and Push IoT Edge Solution».
- Модуль сбилдится и загрузится в репозиторий.
- Опять жмем правую кнопку мышки и выбраем пункт «Generate IoT Edge Deployment Manifest».
- В папке Config будет обновлен файл deployment.json. В нем прописаны полные пути к образам docker, пароли на доступ к репозиторию из файла .env и пр.
- Встаем на deployment.json и кликаем на нем правой клавишей мыши.
- Выбираем пункт «Create Deployment for Single Device».
- Если в Visual Studio Code установлен extension для работы с Azure IoT Hub и пройдена авторизация в IoT Hub, то отобразится список доступных устройств для которых можно развернуть модуль.
- После выбора устройства в IoT Hub будут развернуты все модули перечисленные в файле deployment.json и для них будут перенесены все необходимые настройки, описанные для модулей в properties.desired.