目的
上記のようにMicrosoftドキュメントにAzure IoT SDK for Pythonではジョブ機能がサポートされていないと記載があるが、IoTHubJobManager Classが用意されているようなので実装する
Azure Functions(トリガー:EventGrid)上でダイレクトメソッドを実行するジョブを実装する
実装
デバイス側
ドキュメント通りに実装
クラウドからコールされるダイレクトメソッドの登録を行う
クラウド側
接続文字列の取得はドキュメントを参照
デバイスのダイレクトメソッドをコールするジョブを発行、ジョブ状態の監視を行う
以下実装
__init__.py
import sys
import uuid
import json
import logging
import datetime
import time
import azure.functions as func
from azure.iot.hub import IoTHubJobManager
from azure.iot.hub.models import CloudToDeviceMethod, CloudToDeviceMethodResult, JobRequest
CONNECTION_STRING = ''
METHOD_NAME = 'lockDoor'
METHOD_PAYLOAD = '{\'lockTime\':\'10m\'}'
def executeJob():
try:
deviceMethod = CloudToDeviceMethod(method_name=METHOD_NAME, payload=METHOD_PAYLOAD)
jobId = str(uuid.uuid4())
logging.info('job ID: %s', jobId)
jobRequest = JobRequest(job_id = jobId,
type = 'scheduleDeviceMethod', cloud_to_device_method = deviceMethod,
query_condition = 'deviceId IN [\'myDeviceId\']',
start_time = datetime.datetime.now(datetime.timezone.utc), max_execution_time_in_seconds = 30)
# 接続文字列からジョブマネージャーインスタンスを生成
jobManager = IoTHubJobManager(CONNECTION_STRING)
# ジョブ生成
jobManager.create_scheduled_job(jobId, jobRequest)
# ジョブ状態の監視
while True:
# ジョブ状態の取得
response = jobManager.get_scheduled_job(jobId)
logging.info('job status: %s', response.status)
if response.status != 'running':
break
time.sleep(5)
except Exception as ex:
logging.info('')
logging.info('Unexpected error {0}'.format(ex))
return
except KeyboardInterrupt:
logging.info('')
logging.info('IoTHubDeviceMethod sample stopped')
def main(event: func.EventGridEvent):
result = json.dumps({
'id': event.id,
'data': event.get_json(),
'topic': event.topic,
'subject': event.subject,
'event_type': event.event_type,
})
logging.info('Python EventGrid trigger processed an event: %s', result)
# ジョブ実行
executeJob()
以下ジョブのリクエスト、レスポンスで使用するクラス
ジョブに関する制限事項
- ジョブの最大数は 1 (Free および S1)、5 (S2)、10 (S3) (ドキュメント)
- Azure portal上でジョブの確認、操作ができない
懸念
cancel_scheduled_jobの仕様からジョブ発行後ジョブIDを忘れてしまった場合、ジョブのキャンセルができない、Azure portalからジョブのキャンセルも不可
アカウントがFree および S1の場合はジョブ最大数は1のため、それ以上ジョブの発行ができなくなる
最悪タイムアウトでジョブが終了するようにJobRequest
のmax_execution_time_in_seconds
は必ず設定しておいたほうが良いと思われる