前提
AWS IoTの以下の公式ブログを参考に、デジタルツインを構築し、センサデータの可視化を目指しております。
”IoT デバイスのデジタルツインを構築し、AWS IoT TwinMaker を使用してリアルタイムのセンサーデータを監視する (パート 2/2)”
https://aws.amazon.com/jp/blogs/news/build-a-digital-twin-of-your-iot-device-and-monitor-real-time-sensor-data-using-aws-iot-twinmaker-part-2-of-2/
Timestreamに保存されたデータをLambda関数を用いてIoT Twinmakerで参照しようとしたら、エラーが発生しました。
実現したいこと
エラーが発生しているLambda関数を正常に動かし、
ブログの通りTwinmakerおよびGrafana にてセンサデータの可視化を行いたい。
発生している問題・エラーメッセージ
ブログのpart1,2同様の環境を構築し、part2の5.最終結果まで手順を進め、デバイス側でPythonスクリプトを実行してダッシュボードで値を可視化しようとしたら、ダッシュボードの左上に”!”マークが出て、以下のエラーが表示され値が反映されていないです。
Grafana
1ConnectorFailureException: Lambda function arn:aws:lambda:[region]:[account id]:function:timestreamReader throws exception. Please check your lambda logs for detailed information.
[region]と[account id]には私のAWS情報が記載されております。
Lambda関数がうまく動いていないようなので、CloudWatchにて該当箇所のエラーの中身も確認しました。
CloudWatch
1[ERROR] Runtime.UserCodeSyntaxError: Syntax error in module 'lambda_function': EOL while scanning string literal (lambda_function.py, line 122) 2Traceback (most recent call last): 3 File "/var/task/lambda_function.py" Line 122 4 entity_property_reference_temp['propertyName'] = 'temperature’ 5
該当のソースコード
以下、Lambda関数の中身です。
python
1import logging 2import json 3import os 4import boto3 5 6from datetime import datetime 7 8LOGGER = logging.getLogger() 9LOGGER.setLevel(logging.INFO) 10 11# Get db and table name from Env variables 12DATABASE_NAME = os.environ['TIMESTREAM_DATABASE_NAME'] 13TABLE_NAME = os.environ['TIMESTREAM_TABLE_NAME'] 14 15# Python boto client for AWS Timestream 16QUERY_CLIENT = boto3.client('timestream-query') 17 18 19# Utility function: parses a timestream row into a python dict for more convenient field access 20def parse_row(column_schema, timestream_row): 21 data = timestream_row['Data'] 22 result = {} 23 for i in range(len(data)): 24 info = column_schema[i] 25 datum = data[i] 26 key, val = parse_datum(info, datum) 27 result[key] = val 28 return result 29 30# Utility function: parses timestream datum entries into (key,value) tuples. Only ScalarTypes currently supported. 31def parse_datum(info, datum): 32 if datum.get('NullValue', False): 33 return info['Name'], None 34 column_type = info['Type'] 35 if 'ScalarType' in column_type: 36 return info['Name'], datum['ScalarValue'] 37 else: 38 raise Exception(f"Unsupported columnType[{column_type}]") 39 40# This function extracts the timestamp from a Timestream row and returns in ISO8601 basic format 41def get_iso8601_timestamp(str): 42 # e.g. '2022-04-06 00:17:45.419000000' -> '2022-04-06T00:17:45.419000000Z' 43 return str.replace(' ', 'T') + 'Z' 44 45# Main logic 46def lambda_handler(event, context): 47 selected_property = event['selectedProperties'][0] 48 49 LOGGER.info("Selected property is %s", selected_property) 50 51 # 1. EXECUTE THE QUERY TO RETURN VALUES FROM DATABASE 52 query_string = f"SELECT measure_name, time, measure_value::bigint" \ 53 f" FROM {DATABASE_NAME}.{TABLE_NAME} " \ 54 f" WHERE time > from_iso8601_timestamp('{event['startTime']}')" \ 55 f" AND time <= from_iso8601_timestamp('{event['endTime']}')" \ 56 f" AND measure_name = '{selected_property}'" \ 57 f" ORDER BY time ASC" 58 59 try: 60 query_page = QUERY_CLIENT.query( 61 QueryString = query_string 62 ) 63 except Exception as err: 64 LOGGER.error("Exception while running query: %s", err) 65 raise err 66 67 # Query result structure: https://docs.aws.amazon.com/timestream/latest/developerguide/API_query_Query.html 68 69 next_token = None 70 if query_page.get('NextToken') is not None: 71 next_token = query_page['NextToken'] 72 schema = query_page['ColumnInfo'] 73 74 # 2. PARSE TIMESTREAM ROWS 75 result_rows = [] 76 for row in query_page['Rows']: 77 row_parsed = parse_row(schema,row) 78 #LOGGER.info('row parsed: %s', row_parsed) 79 result_rows.append(row_parsed) 80 81 # 3. CONVERT THE QUERY RESULTS TO THE FORMAT TWINMAKER EXPECTS 82 83 # There must be one entityPropertyReference for Humidity OR one for Temperature 84 entity_property_reference_temp = {} 85 entity_property_reference_temp['componentName'] = 'timestream-reader' 86 entity_property_reference_temp['propertyName'] = 'temperature’ 87 entity_property_reference_temp['entityId'] = 'xxx' 88 89 90 entity_property_reference_hum = {} 91 entity_property_reference_hum['componentName'] = 'timestream-reader' 92 entity_property_reference_hum['propertyName'] = 'humidity’ 93 entity_property_reference_hum['entityId'] = 'xxx' 94 95 96 values_temp = [] 97 values_hum = [] 98 99 for result_row in result_rows: 100 ts = result_row['time'] 101 measure_name = result_row['measure_name'] 102 measure_value = result_row['measure_value::bigint'] 103 104 time = get_iso8601_timestamp(ts) 105 value = { 'doubleValue' : str(measure_value) } 106 107 if measure_name == 'temperature': 108 values_temp.append({ 109 'time': time, 110 'value': value 111 }) 112 elif measure_name == 'humidity': 113 values_hum.append({ 114 'time': time, 115 'value': value 116 }) 117 118 # The final structure "propertyValues" 119 property_values = [] 120 121 if(measure_name == 'temperature'): 122 property_values.append({ 123 'entityPropertyReference': entity_property_reference_temp, 124 'values': values_temp 125 }) 126 elif(measure_name == 'humidity'): 127 property_values.append({ 128 'entityPropertyReference': entity_property_reference_hum, 129 'values': values_hum 130 }) 131 LOGGER.info("property_values: %s", property_values) 132 133 # marshall propertyValues and nextToken into final response 134 return_obj = { 135 'propertyValues': property_values, 136 'nextToken': next_token 137 } 138 139 return return_obj
上記ソースコードについての補足としては、
・環境変数として、TIMESTREAM_DATABASE_NAMEとTIMESTREAM_TABLE_NAMEは参照するTimestreamのデータベース名とテーブル名を設定済み
・上記コードに2か所存在する
entity_property_reference_temp['entityId'] = 'xxx'
には、Twinmakerで作成したエンティティのEntityIdを実際は入力しております。
AWSの使い方があまりわかっていないので、解決するために必要な情報が抜けているかもしれないです。
解決策をご教授願います。
‐‐‐‐‐‐‐‐‐‐追記‐‐‐‐‐‐‐‐‐‐
こちらの行に関するエラーの原因がわかりました。'が全角の’になっていたため発生しておりました。
その部分を修正した結果、新たなエラーが発生しました。
[ERROR] 2022-10-20T07:20:45.195Z 400075f2-8527-4e3b-abba-7b794f2eb1fc Exception while running query: An error occurred (ValidationException) when calling the Query operation: line 1:28: Column 'measure_value::bigint' does not exist [ERROR] ValidationException: An error occurred (ValidationException) when calling the Query operation: line 1:28: Column 'measure_value::bigint' does not exist Traceback (most recent call last): File "/var/task/lambda_function.py", line 109, in lambda_handler raise err File "/var/task/lambda_function.py", line 105, in lambda_handler QueryString = query_string File "/var/runtime/botocore/client.py", line 391, in _api_call return self._make_api_call(operation_name, kwargs) File "/var/runtime/botocore/client.py", line 719, in _make_api_call raise error_class(parsed_response, operation_name)
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。