解决IoT设备消息体无法被本地Azure Functions接收处理的问题
问题:Azure Functions读取IoT Hub消息体时抛出TypeError错误
问题描述
传感器检测到人员并向云端发送数据后,本地VSCode中的Azure Functions无法正确读取消息体,抛出TypeError: list indices must be integers or slices, not str错误。日志显示接收到的消息体为列表类型,其中data.body是Base64编码的业务数据,但代码中直接按字典取值(如date = body['date'])导致索引错误。
期望实现:Azure Functions读取设备发送的消息体,并将数据写入本地MySQL数据库的notifications表。
原代码
import logging import azure.functions as func import mysql.connector import time from datetime import datetime import json import os from azure.iot.hub import IoTHubRegistryManager from azure.iot.hub.models import CloudToDeviceMethod def main(event: func.EventHubEvent): # Connect database MySQL dbconnection = mysql.connector.connect( host = "127.0.0.1", user = "root", password = "", database = "roomdb" ) cursor = dbconnection.cursor() body = json.loads(event.get_body().decode('utf-8')) device_id = event.iothub_metadata.get('automate-device-id') # logging.info(f'Received message: {body} from {device_id}') id = 1 date = body['date'] time = body['time'] temperature = body['temperature'] people = body['people'] detect_time = body['last_detected_time'] notification_type = "" message = "You can view more via website" room_id = 1 sql = "" # Insert into database using the notifications sql = "insert into notifications (id, date, time, value_temperature, number_of_people, notification_type, message, room_id) values (%s, %s, %s, %s, %s, %s, %s, %s)" value = (id, date, time, temperature, people, notification_type, message, room_id) cursor.execute(sql, value) dbconnection.commit() print(cursor.rowcount, 'Data Saved Successfully') cursor.close() dbconnection.close()
错误日志
[2024-01-10T09:57:10.295Z] Executing 'Functions.AutomateHubTrigger' (Reason='(null)', Id=d286be5c-f5e8-4260-9c9e-a6e27de9b87c) [2024-01-10T09:57:10.300Z] Trigger Details: PartionId: 1, Offset: 4294979360, EnqueueTimeUtc: 2024-01-10T09:55:47.2540000+00:00, SequenceNumber: 110, Count: 1 [2024-01-10T09:57:10.306Z] Type of body: <class 'list'>, Content of body: [{'id': 'f6acfe2e-8725-2b54-777d-79b477db2796', 'topic': '/SUBSCRIPTIONS/D0E3660E-537C-4385-89F5-B2B0646AF52A/RESOURCEGROUPS/AUTOMATE/PROVIDERS/MICROSOFT.DEVICES/IOTHUBS/AUTOMATE-HUB', 'subject': 'devices/automate-device-id', 'eventType': 'Microsoft.Devices.DeviceTelemetry', 'data': {'properties': {}, 'systemProperties': {'iothub-connection-device-id': 'automate-device-id', 'iothub-connection-auth-method': '{"scope":"device","type":"sas","issuer":"iothub","acceptingIpFilterRule":null}', 'iothub-connection-auth-generation-id': '638364984370269801', 'iothub-enqueuedtime': '2024-01-10T09:55:47.0870000Z', 'iothub-message-source': 'Telemetry'}, 'body': 'eyJkYXRlIjogIjIwMjQtMDEtMTAiLCAidGltZSI6ICIxNjo1NTo0NiIsICJ0ZW1wZXJhdHVyZSI6IDM0LjAsICJwZW9wbGUiOiAwfQ=='}, 'dataVersion': '', 'metadataVersion': '1', 'eventTime': '2024-01-10T09:55:47.087Z'}] [2024-01-10T09:57:10.310Z] Executed 'Functions.AutomateHubTrigger' (Failed, Id=d286be5c-f5e8-4260-9c9e-a6e27de9b87c, Duration=15ms) [2024-01-10T09:57:10.314Z] System.Private.CoreLib: Exception while executing function: Functions.AutomateHubTrigger. System.Private.CoreLib: Result: Failure Exception: TypeError: list indices must be integers or slices, not str Stack: File "C:\Users\Viqram Wataf\AppData\Roaming\nvm\v10.24.0\node_modules\azure-functions-core-tools\bin\workers\python\3.9\WINDOWS\X64\azure_functions_worker\dispatcher.py", line 406, in _handle__invocation_request call_result = await self._loop.run_in_executor( File "C:\Program Files\Python 3.9.0\lib\concurrent\futures\thread.py", line 52, in run result = self.fn(*self.args, **self.kwargs) File "C:\Users\Viqram Wataf\AppData\Roaming\nvm\v10.24.0\node_modules\azure-functions-core-tools\bin\workers\python\3.9\WINDOWS\X64\azure_functions_worker\dispatcher.py", line 648, in _run_sync_func return ExtensionManager.get_sync_invocation_wrapper(context, File "C:\Users\Viqram Wataf\AppData\Roaming\nvm\v10.24.0\node_modules\azure-functions-core-tools\bin\workers\python\3.9\WINDOWS\X64\azure_functions_worker\extension.py", line 215, in _raw_invocation_wrapper result = function(**args) File "C:\xampp\htdocs\tugas-akhir-project\Tugas-Akhir\azure_function\AutomateHubTrigger___init___.py", line 29, in main date = body['date']
解决方法
错误原因
解析后的消息体是列表类型,列表中包含IoT Hub封装的事件对象,真实业务数据被Base64编码后存储在事件对象的data.body字段中,直接用字典索引访问列表会触发类型错误。
修改后的代码
import logging import azure.functions as func import mysql.connector import time from datetime import datetime import json import os import base64 # 新增:用于Base64解码 from azure.iot.hub import IoTHubRegistryManager from azure.iot.hub.models import CloudToDeviceMethod def main(event: func.EventHubEvent): # Connect database MySQL dbconnection = mysql.connector.connect( host = "127.0.0.1", user = "root", password = "", database = "roomdb" ) cursor = dbconnection.cursor() # 修正:解析消息体为列表,取出第一个事件对象 event_list = json.loads(event.get_body().decode('utf-8')) event_data = event_list[0] # 提取Base64编码的业务数据并解码 raw_business_data = base64.b64decode(event_data['data']['body']).decode('utf-8') business_data = json.loads(raw_business_data) device_id = event.iothub_metadata.get('automate-device-id') # logging.info(f'Received message: {business_data} from {device_id}') id = 1 date = business_data['date'] time = business_data['time'] temperature = business_data['temperature'] people = business_data['people'] detect_time = business_data.get('last_detected_time', '') # 增加容错,避免字段缺失报错 notification_type = "" message = "You can view more via website" room_id = 1 # Insert into database using the notifications sql = "insert into notifications (id, date, time, value_temperature, number_of_people, notification_type, message, room_id) values (%s, %s, %s, %s, %s, %s, %s, %s)" value = (id, date, time, temperature, people, notification_type, message, room_id) cursor.execute(sql, value) dbconnection.commit() print(cursor.rowcount, 'Data Saved Successfully') cursor.close() dbconnection.close()
关键修改点
- 新增
base64模块导入,用于解码Base64格式的业务数据 - 调整消息体解析逻辑:先获取事件列表中的第一个对象,再提取并解码
data.body中的真实业务数据 - 所有业务字段的取值改为从解码后的
business_data字典获取 - 增加
business_data.get('last_detected_time', '')容错处理,避免字段缺失导致报错
内容的提问来源于stack exchange,提问作者VIQRAM ANANTA WATAF
相关产品推荐
相关产品推荐

