chakokuのブログ(rev4)

テック・コミック・ごくまれにチャリ

作りかけて放置したFlutterアプリをもう少し作る(スマートメータ表示アプリ)

昨日、定年サポートアプリを久しぶりにビルドして、スマフォアプリももうちょっと作り込まないとなーと思ったので、作りかけで放置してたFlutterによる電力データ表示アプリをもう少し仕上げることにした。

前回のアプリの実装状態

作り込みたい機能
1. スマフォアプリを起動したら電力値がMQTTで配信開始されるようにする(自動化が難しかったらボタン押下)
2. 最新データ取得機能(待ってられない場合に、更新ボタンを押したら最新の電力データがグラフに反映される)
3. スマフォからのアクセスがなくなったら、MQTTによる配信を自動で止める

経緯
かつて、自宅のメータをスマートメータに変えて、電力データを取れるようにNature remo E Liteを入れて、AWS LambdaからNature社のWebAPIを叩いて自宅の電力データを取得して、AWS IoT Coreを使ってMQTTで配信してスマフォで見るところまでは作った。
が、、ビジュアルに訴えるにはサンプリング周期を30秒程度で行う必要があり、ずっと30秒で上記経路を動かしているとお金がかかってしょうがない。だから、1時間周期でCRONで走らせて積算値をS3に蓄える*1以外、MQTT配信は止めていた。スマフォで見たい時だけ30秒周期のCRONを走らせてMQTT配信して、見たくなくなったらCRONを止めるというあり得ない仕様であった。利用者にMQTT配信のOn/Offをさせるのではなく、スマフォアプリの接続状態を感知して自動で配信のOn/Offするように仕込みたい。

■追記
久しぶりにFlutter動かそうと思ったらどうやってビルドしていたか、テストはEmulatorだったか実機だったかも忘れた。普段Flutter使っていたら当たり前のことだけど、時間が経つと当たり前の知識が消失している。暗黙知(俺)というやつか。暗黙知は時間が経つと消えてしまう。だから、、当たり前でもビルド手順とかインストール手順とかはメモに残すか、batch でシェル化しておかないと思い出せない。Terminalのhistoryコマンドでも当時の操作記録は古すぎて出てこないだろう。。

■追記
iOSのshellでgrepしてみた。当時の操作履歴が残っていた。なるほど、、こういうコマンドだったか。。
(理解しやすくなるよう上下入れ替えています)

$ history 0 | grep flutter
   67  flutter emulators
   69  flutter devices
   84  flutter build
   85  flutter build ios
   68  flutter emulators --launch iOS
   73  flutter emulators --list
   74  flutter emulators 
   70  flutter run -d iPhone
   75  flutter run --release

iPhoneMacに接続した状態で、command historyを頼りに以下を実行した。

flutter run

iPhoneには画面が表示されて、AWS IoT Coreには接続できた(Client証明書も生きてるようだ)

利用者の立場では困惑しかないだろうが、定期収集のCRONをユーザがOn/Offする仕様で実装。以下がCRON制御付きの画面(update, start , stop のボタンが増えている)

本来、これらの操作は自動化できるはずなので、今後改定する

テストしている際、IoT Coreに接続できない時があり以下のエラーが出る。エラーメッセージが、Failed host lookupなので、ホスト名が解決できないか、ホストに到達できないような言いぶりだ。なぜだろうか。エラーになる前にすでに先方から怒られているような。。

flutter: 1-2022-07-10 16:23:35.769250 -- MqttConnectionKeepAlive::pingRequired - restarting ping timer
flutter: 1-2022-07-10 16:23:35.948536 -- MqttConnectionBase::_onError - calling disconnected callback
flutter: *** in fail ***
flutter: SocketException: Failed host lookup: 'a3xxxxxxxt-ats.iot.ap-northeast-1.amazonaws.com' (OS Error: nodename nor servname provided, or not known, errno = 8)
flutter: 1-2022-07-10 16:23:35.968145 -- MqttConnectionHandlerBase::disconnect - entered
flutter: 1-2022-07-10 16:23:35.970955 -- MqttConnectionHandlerBase::_performConnectionDisconnect entered
flutter: 1-2022-07-10 16:23:35.980196 -- MqttConnectionKeepAlive::stop - stopping keep alive
flutter: *** disconnected ***
flutter: Subscribing to the topic:[topic_1]
[VERBOSE-2:ui_dart_state.cc(209)] Unhandled Exception: mqtt-client::ConnectionException: The connection must be in the Connected state in order to perform this operation.
#0      MqttClient.subscribe (package:mqtt_client/src/mqtt_client.dart:345:7)
#1      _MyHomePageState._connect (package:awsiot/main.dart:182:12)
<asynchronous suspension>

原因は、スマフォ内でWiFiと正常に接続できない状況になっていたため。電波をつかんでいるアイコンは出ているが、アプリによるのか、疎通できない場合がある。スマフォのWiFiをOff/Onしたら正常化した

IoT Coreに向けてMQTTで topic: viewer/requestで投げると IoT CoreのMessage RoutingのruleにマッチしてLambdaがキックされるようにした。Lambdaは以下のような内容で、1分定期CRON(execute_every_1min)のOn/Offを制御できるようにした。On/Offを手動で操作しないといけないのがなんともイマイチだけど、スマフォからできるようになったので、今日のところはここまで

import json
import boto3
client = boto3.client('events')
RULE_NAME = 'execute_every_1min'

def lambda_handler(event, context):
    global client
    
    # TODO implement
    print("----!!!!-------")
    print(event)
    # 
    if event['msgType'] == 'request':
        if event['request'] == 'start_CRON':
            print('going enable')
            client.enable_rule(Name=RULE_NAME)
        elif event['request'] == 'stop_CRON':
            print('going disable')
            client.disable_rule(Name=RULE_NAME)
            
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

MQTTで電力データを表示、CRONをOn/Offするフローまとめ

<CRON On/Off>
[SmartPhone]--(pub)-->[IoT Core]--(Route)-->[Lambda]--->[EventBridge]

<Report>
[EventBridge]-->[Lambda]  [Nature API]   [IoT Core]     [SmartPhone]  
                   |--------->|             |               |
                   |<---------|             |               |
                   |----------------------> |               |
                                            |----(pub)----> |

Flutter CLIメモ

% flutter build ios     // release版のビルド
% flutter install        // iPhoneへのインストール

■課題
安定してMQTTブローカと接続できない印象で、本当にCRON制御できているか、かなり不安なので、状態報告機能を強化したい。このままでは任せられない。

*1:データレークというやつでしょうか