質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.53%
AWS Lambda

AWS Lambdaは、クラウド上でアプリを実行できるコンピューティングサービス。サーバーのプロビジョニングや管理を要せず複数のイベントに対してコードを実行します。カスタムロジック用いた他AWSサービスの拡張やAWSの規模やパフォーマンスを用いたバックエンドサービスを作成できます。

Grafana

Grafanaは、Grafana Labsが公開しているオープンソースのデータ時系列分析用ダッシュボードツール。1つのWebインターフェースで複数データソースの統計情報を確認することが可能です。リッチなグラフ描画により、リアルタイムでステータスを把握できます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

Q&A

解決済

1回答

1113閲覧

AWS Timestreamからデータを取得するLambda関数のエラー

y_hosokawa

総合スコア2

AWS Lambda

AWS Lambdaは、クラウド上でアプリを実行できるコンピューティングサービス。サーバーのプロビジョニングや管理を要せず複数のイベントに対してコードを実行します。カスタムロジック用いた他AWSサービスの拡張やAWSの規模やパフォーマンスを用いたバックエンドサービスを作成できます。

Grafana

Grafanaは、Grafana Labsが公開しているオープンソースのデータ時系列分析用ダッシュボードツール。1つのWebインターフェースで複数データソースの統計情報を確認することが可能です。リッチなグラフ描画により、リアルタイムでステータスを把握できます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

0グッド

1クリップ

投稿2022/10/20 06:22

編集2022/10/20 16:56

前提

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)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

解決済み
SQL辺りがいろいろ間違っている

投稿2022/10/20 07:56

y_hosokawa

総合スコア2

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.53%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問