あるけみーの小屋

趣味の話とか色々

Raspberry Pi工作日記③~AWS編(完結編)~

前回のあらすじ

CO2濃度の値が取れた。

fieldpaddy.hatenablog.com

本日のお品書き

  • AWSアカウント作るよ
  • センサーデータをAWSに送るよ

AWSアカウント作成

必要事項を入力して淡々と進める。

 

ほい完了。

 

今回久々に個人アカウントを作成しましたが、IAM Identity Centerなるものが使えるようになっていたのでこちらを有効にしてやってみました。IAM ユーザを作らなくて良くなりました。

 

あとは、

  • MFA認証の設定
  • Budgetの設定
  • Cost Anomalry Detectionの設定

だけ最低限設定。本当はCloudTrailとかSecuriyHubとか諸々やった方が良いんだけどね。

 

センサーデータをAWSに送信

さて、AWSアカウントの準備ができたのでセンサーデータをAWSに送信していく。

IoT Coreというサービスを使っていくのだが、実は先駆者がいるのでこちらを参考にしてみる。

 

 

dev.classmethod.jp

 

まずはIoT Coreで検索してページ遷移。

 

管理の「すべてのデバイス」>「モノ」を選択し、「モノを作成」

 

1つのモノを作成。

 

名前だけ入力し、あとはデフォルト。

 

証明書は自動生成

 

ポリシーは特にアタッチせずにそのまま

 

作成されたデバイス証明書等をすべてダウンロードしておきます。

 

 

ポリシーを作成します。

 

ポリシーアクションとポリシーリソースはここでは「*」にしますが、実運用では制限をかけた方が良さそう。

 

作成したポリシーを先ほど作った証明書にアタッチ。

 

この時点で、証明書を持っているモノからデータを送信できる状態になりました。

 

github.com

実際にデータを送るために、こちらのgitをラズパイ上でcloneします。

git clone https://github.com/aws/aws-iot-device-sdk-python.git

 

AWSIoTPythonSDKというライブラリをインストールしておきます。

pip3 install AWSIoTPythonSDK

 

その後、basicPubSub.pyをendpointなどのオプションをつけて実行する。

python3 basicPubSub.py --endpoint xxxxxxxx.iot.ap-northeast-1.amazonaws.com --rootCA ~/cert/AmazonRootCA1.pem --cert xxxxx-certificate.pem.crt --key xxxxxx-private.pem.key 

 

すると、

2024-04-06 16:33:35,125 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Initializing MQTT layer...
2024-04-06 16:33:35,131 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Registering internal event callbacks to MQTT layer...
2024-04-06 16:33:35,134 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - MqttCore initialized
2024-04-06 16:33:35,136 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Client id: basicPubSub
2024-04-06 16:33:35,139 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Protocol version: MQTTv3.1.1
2024-04-06 16:33:35,141 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Authentication type: TLSv1.2 certificate based Mutual Auth.
2024-04-06 16:33:35,143 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Configuring endpoint...
2024-04-06 16:33:35,146 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Configuring certificates and ciphers...
2024-04-06 16:33:35,149 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Configuring reconnect back off timing...
2024-04-06 16:33:35,151 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Base quiet time: 1.000000 sec
2024-04-06 16:33:35,153 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Max quiet time: 32.000000 sec
2024-04-06 16:33:35,155 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Stable connection time: 20.000000 sec
2024-04-06 16:33:35,157 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Configuring offline requests queueing: max queue size: -1
2024-04-06 16:33:35,172 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Configuring offline requests queue draining interval: 0.500000 sec
2024-04-06 16:33:35,175 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Configuring connect/disconnect time out: 10.000000 sec
2024-04-06 16:33:35,177 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Configuring MQTT operation time out: 5.000000 sec
2024-04-06 16:33:35,179 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Performing sync connect...
2024-04-06 16:33:35,181 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Performing async connect...
2024-04-06 16:33:35,183 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Keep-alive: 600.000000 sec
2024-04-06 16:33:35,187 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Event consuming thread started
2024-04-06 16:33:35,189 - AWSIoTPythonSDK.core.protocol.mqtt_core - DEBUG - Passing in general notification callbacks to internal client...
2024-04-06 16:33:35,191 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Filling in fixed event callbacks: CONNACK, DISCONNECT, MESSAGE
2024-04-06 16:33:35,413 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Starting network I/O thread...
2024-04-06 16:33:35,476 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Produced [connack] event
2024-04-06 16:33:35,477 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Dispatching [connack] event
2024-04-06 16:33:35,482 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - No need for recovery
2024-04-06 16:33:35,484 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Invoking custom event callback...
2024-04-06 16:33:35,487 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Performing sync subscribe...
2024-04-06 16:33:35,489 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Adding a new subscription record: sdk/test/Python qos: 1
2024-04-06 16:33:35,492 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Filling in custom suback event callback...
2024-04-06 16:33:35,561 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Produced [suback] event
2024-04-06 16:33:35,563 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Dispatching [suback] event
2024-04-06 16:33:35,566 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Invoking custom event callback...
2024-04-06 16:33:35,569 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - This custom event callback is for pub/sub/unsub, removing it after invocation...
2024-04-06 16:33:37,572 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Performing sync publish...
2024-04-06 16:33:37,579 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Filling in custom puback (QoS>0) event callback...
2024-04-06 16:33:37,598 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Produced [puback] event
2024-04-06 16:33:37,600 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Dispatching [puback] event
2024-04-06 16:33:37,605 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Invoking custom event callback...
2024-04-06 16:33:37,608 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - This custom event callback is for pub/sub/unsub, removing it after invocation...
2024-04-06 16:33:37,626 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Produced [message] event
2024-04-06 16:33:37,629 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Dispatching [message] event
Received a new message: 
b'{"message": "Hello World!", "sequence": 0}'
from topic: 
sdk/test/Python
--------------

といった形でAWSにテストメッセージが送信されるようになりました。

 

AWSコンソール上でも確認してみます。

MQTTテストクライアントからトピックを指定して、サブスクライブしておきます。

 

この状態で、先ほどのbasicPubSub.pyを実行すると

AWS側に送信されていることが確認できました。

 

これをベースにプログラムを書き換えました

from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient
import logging
import time
import argparse
import json
import mh_z19 #ライブラリをインポート

AllowedActions = ['both', 'publish', 'subscribe']

# Custom MQTT message callback
def customCallback(client, userdata, message):
    print("Received a new message: ")
    print(message.payload)
    print("from topic: ")
    print(message.topic)
    print("--------------\n\n")


# Read in command-line parameters
parser = argparse.ArgumentParser()
parser.add_argument("-e", "--endpoint", action="store", required=True, dest="host", help="Your AWS IoT custom endpoint")
parser.add_argument("-r", "--rootCA", action="store", required=True, dest="rootCAPath", help="Root CA file path")
parser.add_argument("-c", "--cert", action="store", dest="certificatePath", help="Certificate file path")
parser.add_argument("-k", "--key", action="store", dest="privateKeyPath", help="Private key file path")
parser.add_argument("-p", "--port", action="store", dest="port", type=int, help="Port number override")
parser.add_argument("-w", "--websocket", action="store_true", dest="useWebsocket", default=False,
                    help="Use MQTT over WebSocket")
parser.add_argument("-id", "--clientId", action="store", dest="clientId", default="basicPubSub",
                    help="Targeted client id")
parser.add_argument("-t", "--topic", action="store", dest="topic", default="co2/value", help="Targeted topic")  #デフォルトの送信先Topicを変更
parser.add_argument("-m", "--mode", action="store", dest="mode", default="both",
                    help="Operation modes: %s"%str(AllowedActions))
parser.add_argument("-M", "--message", action="store", dest="message", default="Hello World!",
                    help="Message to publish")

args = parser.parse_args()
host = args.host
rootCAPath = args.rootCAPath
certificatePath = args.certificatePath
privateKeyPath = args.privateKeyPath
port = args.port
useWebsocket = args.useWebsocket
clientId = args.clientId
topic = args.topic

if args.mode not in AllowedActions:
    parser.error("Unknown --mode option %s. Must be one of %s" % (args.mode, str(AllowedActions)))
    exit(2)

if args.useWebsocket and args.certificatePath and args.privateKeyPath:
    parser.error("X.509 cert authentication and WebSocket are mutual exclusive. Please pick one.")
    exit(2)

if not args.useWebsocket and (not args.certificatePath or not args.privateKeyPath):
    parser.error("Missing credentials for authentication.")
    exit(2)

# Port defaults
if args.useWebsocket and not args.port:  # When no port override for WebSocket, default to 443
    port = 443
if not args.useWebsocket and not args.port:  # When no port override for non-WebSocket, default to 8883
    port = 8883

# Configure logging
logger = logging.getLogger("AWSIoTPythonSDK.core")
logger.setLevel(logging.DEBUG)
streamHandler = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
streamHandler.setFormatter(formatter)
logger.addHandler(streamHandler)

# Init AWSIoTMQTTClient
myAWSIoTMQTTClient = None
if useWebsocket:
    myAWSIoTMQTTClient = AWSIoTMQTTClient(clientId, useWebsocket=True)
    myAWSIoTMQTTClient.configureEndpoint(host, port)
    myAWSIoTMQTTClient.configureCredentials(rootCAPath)
else:
    myAWSIoTMQTTClient = AWSIoTMQTTClient(clientId)
    myAWSIoTMQTTClient.configureEndpoint(host, port)
    myAWSIoTMQTTClient.configureCredentials(rootCAPath, privateKeyPath, certificatePath)

# AWSIoTMQTTClient connection configuration
myAWSIoTMQTTClient.configureAutoReconnectBackoffTime(1, 32, 20)
myAWSIoTMQTTClient.configureOfflinePublishQueueing(-1)  # Infinite offline Publish queueing
myAWSIoTMQTTClient.configureDrainingFrequency(2)  # Draining: 2 Hz
myAWSIoTMQTTClient.configureConnectDisconnectTimeout(10)  # 10 sec
myAWSIoTMQTTClient.configureMQTTOperationTimeout(5)  # 5 sec

# Connect and subscribe to AWS IoT
myAWSIoTMQTTClient.connect()
if args.mode == 'both' or args.mode == 'subscribe':
    myAWSIoTMQTTClient.subscribe(topic, 1, customCallback)
time.sleep(2)

# Publish to the same topic in a loop forever
loopCount = 0
while True:
    if args.mode == 'both' or args.mode == 'publish':
        message = {}
        messageJson = json.dumps(mh_z19.read())  #修正
        myAWSIoTMQTTClient.publish(topic, messageJson, 1)
        if args.mode == 'publish':
            print('Published topic %s: %s\n' % (topic, messageJson))
        loopCount += 1
    time.sleep(10) #適宜送信間隔を修正

 

主に太字の箇所のみ修正しています。これで同じようにトピックでサブスクライブしてプログラムを動かしてみます。

 

良い感じに値が取れました!

 

さて、この値をCloudWatchに送信できるようにします。

 

まずIoT Core上でルールを作成します。

名前を設定

 

SQLステートメントはこんな感じで設定。FROM句にIoT Coreの送信先トピック名を記載。FROMの値は必ずシングルクォートを入れて文字列になるようにしましょう(1敗)



 

ルールアクションではCloudWatch Logsに送信できるように、ロググループとIAMロールを作成。

 

あとは確認して作成。

※上記のSQLステートメントは間違えた時の値が入っています。FROM句には文字列を入れましょう。

 

それではプログラムを動かして、CloudWatchにログが来ているかを確認。

いっぱいきた。

 

中身も問題なし。

 

値をグラフ化する

ログで値を取れたので、今度は可視化してみる。

ログからメトリクスフィルターを設定する。

 

こんな感じでフィルターパターンを設定

 

 

メトリクスの詳細はこんな感じ。デフォルトを400にしたのは、センサーで取得できる下限値が400のため。

 

グラフで表示できるようになった。

 

異常時にメールを飛ばすようにする

この調子でアラームの設定もしてみる。

 

10秒おきに取得するようにし、1000を超える値が6連続(=1分)発生したらアラーム状態になるようにした。

 

SNSトピックを一緒に作った場合、アラーム作成後はConfirmメールが届くので確認すること。

 

こんな感じでアラームの設定ができた。

なお、通知はアラーム状態になったタイミングで来るので、すでにアラーム状態であった場合メールは来ない。

 

というわけで元々やりたかったことは完了!

 

今回の進捗報告

  • AWSアカウント作成
  • AWSにセンサーデータ送信
  • CO2濃度が高くなった時にメール通知されるようにした

というわけで本来の目的は達成したので、このシリーズは完。

細かいチューニングはどっかでまとめるかも。

Raspberry Pi工作日記②~導入編~

前回のあらすじ

突如電子工作に目覚めたあるけみーにアイデアが降ってくる。

fieldpaddy.hatenablog.com

 

本日のお品書き

  • 届いたRaspberry PiにOSをインストールするよ
  • mh_z19ライブラリインストールするよ

ラズパイ届く

妻に「それ何?」って聞かれたので、「ラズベリーパイだよ」と答えたら「お菓子じゃないじゃん」というテンプレ通りの会話をしたところで開封の儀。

想像していたよりもかなり小さい。

 

 

どれくらい小さいか、普段使ってるボールペンと比較してみた。(既にヒートシンクをつけたあとだが…)

 

一緒に買ったケースキット。

中身を色々みてみると、

ディスプレイと接続するためのコネクタ(HDMI↔︎TypeB)や、電源ケーブル(TypeC)、USBハブ(TypeB)など、絶妙に自宅になかったものたち。電源ケーブルはないこともないが、必要なもの+あったら嬉しいものが勢揃い。

というわけでヒートシンク(CPUの排熱用)とケースをつけたものがこちら。

 

さて、OSでもインストールするかーと思った矢先。重大な事に気づく。

 

「(あるはずの)microSDカードなくね?」

 

そんなわけ…と過去を思い返したが、

 

  1. Nintendo SwitchのSDカードを容量が大きいものにデータ移行する
  2. 元々使っていたSDカードを放置(←これがあると思っていた)
  3. 古いNintendo Switchを妹にあげる時、2.のSDカードも一緒に渡す(←この記憶が抹消されていた)

 

…というわけでこの日の作業は中断された。

 

後日

物理配線

CO2センサーが届いた。ということで接続するかーとは思ったものの、

 

基盤に書いてある文字の意味が分からない。TxとRxは送信受信ってことはわかるけど、他はよく分からん。

 

ということで色々調べてみる。

 

ラズパイ(Raspberry Pi)のGPIOを再確認! | Device Plus - デバプラ

 

MH-19Cのデータシートを発掘した。

https://www.winsen-sensor.com/d/files/infrared-gas-sensor/mh-z19c-pins-type-co2-manual-ver1_0.pdf

 

分からん。

 

Parts:Sensor:MH-Z19C - robot-jp wiki

 

pypi.org

 

とりあえず、

で繋げば良さそう?

 

公式のページも参考につないでみた。

https://www.raspberrypi.com/documentation/computers/raspberry-pi.html

 

こんな感じ。どうでも良いけどケーブルがめっちゃ臭かった。

 

電源もつないでみると。。。

光った!少なくとも電源周りは良さそう。

 

とりあえず接続関係は一旦置いといて、OSのインストールへ。

OSインストール

microSDが届いた。

 

 

ラズパイにはデフォルトではOSが入っていない。なのでOSを入れる必要があるのだが、その際にmicroSDにOS Imageを入れて、それをラズパイに挿し起動する流れとなる。

 

下記に従ってやってみる。

https://projects.raspberrypi.org/ja-JP/projects/raspberry-pi-getting-started/3

 

まずはOSのダウンロードページに飛び、使ってるPCに応じたDLボタンを押す。今回はmacOS

https://www.raspberrypi.com/software/

 

インストールした.dmgファイルをクリック。

例によってApplicationsフォルダへドラッグ。

 

その後、アプリケーションを起動。

 

バイスRaspberry Pi Zero W

OS:Recommendedがついているやつ。

ストレージ:microSDを選ぶ

 

 

Legacyって書いてあるのが気になったが、推奨されているから仕方がない。

 

microSDを挿したら選択できるようになる。

 

次へを押したらどうやら設定が編集できそうだったので、WiFi情報とか入れた。多分後から設定できるのでここは「いいえ」を選択しても問題なさそう。

 

書き込み中

 

 

完了!

起動してみる

モバイルディスプレイに繋いで起動すると、最初のトップ画面(OSの起動画面)は映るものの、そのあとでディスプレイの出力が止まってしまう。なぜだなぜだと思って色々調べてみたら、どうやらディスプレイによってはうまく出力されないようだ。

 

というわけで普段テレワークで使ってるディスプレイに切り替えてみた。

映った!

 

画面の指示に従って必要情報を入力していく。

 

最後にソフトウェアアップデートも完了したら(結構時間かかった)再起動。

 

できた!

 

ライブラリインストール

このままラズパイのGUIでもできるが、作業が色々面倒になりそうなのでSSH接続できるようにした。

GUIからは設定>Raspberry Piの設定>インターフェースのところからSSHを有効にする。コマンドでもできるので要チェック。

下記を参考にしている。

ラズベリーパイをリモート操作(SSHコマンド)

 

その後SSHができることを確認

> ssh xxxxxxxxx@raspberrypi.local                                                                                    
xxxxxxxxx@raspberrypi.local's password: 
Linux raspberrypi 6.1.21+ #1642 Mon Apr  3 17:19:14 BST 2023 armv6l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Thu Apr  4 22:42:06 2024
xxxxxxxxx@raspberrypi:~ $ 

xxxxxxxxxは自身で設定したユーザ名を入力する。

 

それでは下記GitHub等を参考に作業を進める。

github.com

 

xxxxxxxx@raspberrypi:~ $ git clone https://github.com/UedaTakeyuki/mh-z19.git

まずはgit clone(gitもデフォルトで入ってるんだ)

 

xxxxxxx@raspberrypi:~ $ cd mh-z19/
xxxxxxx@raspberrypi:~/mh-z19 $ ./setup.sh 

その後setupスクリプトを実行。再起動を促されるので再起動する。

スクリプトの中身をみると、シリアル通信が有効化されるっぽい。

 

xxxxxxx@raspberrypi:~ $ sudo pip3 install mh_z19

mh_z19のライブラリをインストール。

 

xxxxxxx@raspberrypi:~ $ sudo python3 -m mh_z19 
{"co2": 2021}

値がとれた!

 

 

 

けど、ありえんくらい値高くない????(とりあえず窓開けた)

 

今回の進捗報告

  • 配線完了
  • Raspberry PiにOS入れて起動確認
  • mh_z19ライブラリを入れてセンサーの値が取れることを確認

次回の作業予定

  • AWSアカウント作成(今回やろうと思ったけど、OSインストールに時間かかったから次回)
  • センサーからAWSにセンサーデータを送れるようにする

Raspberry Pi工作日記①~調査編~

ある日のこと

エンジニアとして社会人生活は送っているはものの、これといって0から自分で何かを作ったことはないと思った。一方で、これといって作りたいものがあるわけでもなかった。言わば、「プログラミングをやりたいです!」「何か作りたいものでもあるの?」「...?」みたいなIT未経験者状態。作りたいものというより、「AWSが使えて」「プログラミングもできて」「ついでにモノとして何か残る」という自分に都合が良すぎることばかりを求めていた。

ある日、システム運用監視の場面を想像しあの写真が脳裏をよぎった。(何故?)

よくシステム運用監視の場面ではシステム障害時に赤く点灯したりするやつである。

色んな使い方はあるとはいえ、何らかの閾値を超過もしくは下回ることでアラートを出す仕組みである。僕の運用時代はこれが側にあったことはなく流れる数値をひたすら眺めることが多かったものだが、なんだか無性に憧れてしまった。とはいえ、何を計測・監視するのかはいまいちピンと来なかった。

そんな時、こんなアイデアをもらった。

 

「天気、気圧、乾燥度、二酸化炭素濃度等で換気促すランプとか簡単そう」

 

なるほど、簡単かどうかはさておきこれは良いアイデアだなと思った。というのも温度や湿度は結構自宅にあるもので表示され入るのだが、二酸化炭素濃度を計測するものは皆無であった。二酸化炭素濃度を測定する機械自体は結構世の中にあるのだが、お金出してまではいらないかなーと思っていた。そんな中出てきたこのアイデア。「(家に)無ければ作れば良いじゃない」というエンジニア思考が久々に湧いてきたのであった。

構成図

まずは構成を考えてみた。

AWS側だけ解像度が高いのはマジで許して欲しい

...

......

………

…………あれ?

 

 

 

 

 

 

ポケモンのパーティ考察のごとく、一番最初に使いたいポケモンが最終的にいなくなったら完成みたいなことになっているが、言い訳させてほしい。いきなりあれもこれも詰め込むと開発はロクなことにならないということを僕らはよく知っている。なので開発スコープを調整して、まずは最低限の機能を備えたものを作ろうという魂胆だ。みんなも開発スコープの調整はちゃんとやろう!

 

???「いいからやれ」

???「…はい」

 

何が必要か

さて、何が必要か調査することにした。

二酸化炭素濃度計測センサー

まずはこれがないとコンセプト崩壊する。温度など計測している場合ではないのだ。Googleさんに聞いてみた。

 

MH-Z19Cというのが引っかかった。MH-Z19Bというのもありそうだが、Cの方が新そう。

https://amzn.asia/d/5ke4HaP

https://akizukidenshi.com/catalog/g/g116142/

 

ChatGPTにも聞いてみた。


Sensirion SCD30は湿度・温度も計測してくれそう。

https://www.sensirion.com/jp/products/product-catalog/SCD30/

 

Senseair S8はCO2濃度だけ計測だが、閾値があらかじめ設定されており、アラームを出すことができるそう。

Senseair S8(6機種)|製品一覧|センスエア

 

MH-Z19Cは他センサに比べると、計測できるCO2濃度の範囲が400ppm~5000pmと少し狭い。この狭さが影響することはあるか少し調べてみた。

 

下の画像を見る限り、測定可能最大値が5000ppmだろうが10000ppmであろうが生命の危機になることは変わらないので今回の場合は範囲の狭さは問題にならないであろう。また、1000ppmが換気の基準になるという知見も得た。

ちなみにppmはparts per millionの略で、10の-6乗(=0.000001)を表し、濃度の単位でよく使われるらしい。

CO2濃度測定器

出典:https://www.leaffresh.jp/item/other/item24.html

 

ちょうど秋月電子さんで他2つと比べて安く買えそうだったので、MH-Z19Cを買おう。

 

Raspberry Pi

よくお菓子と間違えられることで有名なもの。CPUなどを搭載しており小型のコンピュータ…というくらい浅い知識しか持っていない私。実はこの歳になるまで存在は知りつつも実際に扱ったことはない。前々からこれを使って何か作りたいと思っていたが、とうとうこの時が来た。さて必要なものを調べる。

ありがたいことに、公式に良いページがあった。

https://projects.raspberrypi.org/ja-JP/projects/raspberry-pi-getting-started/0

  • SDカードまたはマイクロSDカードを搭載したRaspberry Piコンピューター
    これが本体に当たる部分だろう。色んなモデルがあるので選定は後述。
  • ケーブル付きモニター (および、必要に応じて HDMI アダプター)

    これはすでに自宅にあるので新規購入は不要

  • USBキーボードとマウス

    これはすでに自宅にあるので新規購入は不要

  • 電源
    なんかケーブルあれば良い?
  • ヘッドフォン、またはスピーカー(オプション)
    音も拾えるのか…今回のケースは不要
  • イーサネットケーブル(オプション)
    必要になったら自宅にあるものを使う

あとはOSのインストールにmicroSDカードが必要になりそうだが、これも自宅に使っていないものがあるので新規購入は不要。

基本は本体あればOKかなー。

 

下記ページでいくつか紹介されているが、

  • Wi-Fiで無線接続できること
  • スペックはそこまで高くなくて良い(コスパ重視)
  • 半田付け等が不要であること

これらの点を踏まえ、「Raspberry Pi Zero WH」が良さそう。

ラズベリーパイの5つの種類、失敗しない選び方、おすすめ入門機

 

というところまで決めて、先人の知恵を借りつつ「ラズパイ用のケース」と「ジャンパージャンパーケーブル」をついでに買えば良さそうという結論に至った。

ラズパイでCO2濃度を測定してPlotly Dashで可視化 #Python - Qiita

 

AWSアカウント

クレカとメルアドがあれば秒で作成できるので次回実施。

 

今回の進捗報告

次回の作業予定

  • AWSアカウントを作る
  • Raspberry Piの初期設定(OS入れるところまで)

 

こんな感じでゆるーく作業を進めていきますので見守ってください。

 

(余談)

はてなブログさんにもAIの波が来ているようで、記事の内容からタイトルを考えてくれる機能があったので試しにやってみた。「エンジニアの日常から生まれたIoTプロジェクト」とか良さそうだけど、どうもプログラミング/IT初心者と思われているのか。。。。。

 

 

【Splatoon3】全ブキ熟練度☆1になったので使い勝手をランキングしてみた

先日、全ブキの熟練度が☆1になった。元々ガチャを回すために、ブキチライセンス欲しさにこのイカれた行為に走ったが、想像より強いと思ったブキと想像を下回る(=苦行)ブキがあったので勝手にランキングしてみる。

 

普段のプレイ

スプラ3ではスプラシューターをメインに使っている。なので、ここで紹介するランキングではシューター系統はほぼ入らない。射程やサブスペでおおよその立ち回りを変えていけばそれほど時間はかからなかった。

時間効率を考えて、基本的にバンカラマッチ(オープン・チャレンジ)で回していた。ただし、あまりにも苦行だったブキは気分転換がてらナワバリでやることもあった。

 

ランキングの集計基準

今回は開始当初で☆1になっていないブキの中で「想像していたよりも強かったブキ」「想像していたよりも弱かったブキ」2つの基準でランキングしてみた。

「想像していたよりも」というところがポイントで、強いと思っていたブキが予想通り強かったとしてもランキングには載らない。いわば使用前後でどれくらいギャップがあったかが基準である。

あと、当然だがこのランキングは絶対的な強さを示すものでもないし、あくまで普段スプラシューターしか使っていない人間がどう思ったかのランキンでしかないので、決してブキ批判をするものではないことにご留意いただきたい。(ボロクソ言ってたらすまん)

1/24時点のv6.1.0(スプラトゥーン3 更新データ|Nintendo Switch サポート情報|Nintendo)は反映されていない点に注意。

 

では最初はつよつよランキングから。

 

想像よりも強かったブキ

第4位:キャンピングシェルター系統S3_Weapon_Main_Tenta_Brella.png

元々、パージしてホコ運んだら強くね?くらいにしか思っていなかったが、意外と通り距離までダメージが出るのと、意外と確1で倒せたのでかなり使用感はよかった。特に特にソレーラの方はトラップ・ウルショという最高の組み合わせだったということもあり満足。無印のサブスペも個人的には好きな組み合わせ。

第3位:リッター系統

元々強いとは思っていたが、その上を行く強さだった。縦長ステージが多いことで、最長射程はやっぱり強すぎる。裏どりの警戒はほどほどにしておけばやられた数は基本少なくなるので、あとは当てられるかどうかの勝負。他FPS/TPSでスナイパー武器はあんまり使わないけど、スプラ3は大分当てやすいと思う。ペナアップリッターは犯罪なのでマッチングしないでください(懇願)。

第2位:トライストリンガー系統

 


これはかなり意外だった。発売当初使った時は良さを見出すことができなかったが、今回は「確1を狙うのではなく、飛沫で圧をかける」ことを意識した結果大幅に立ち回りがしやすくなった。意外と時間あたりの塗りも悪くないように感じたので、チームに遠距離ブキが欲しい時は今後も使おうと思う。

第1位:ボトルガイザー系統

一番の誤算。シューター系統ばっか使ってたくせに、スプラ2で登場した際の感想は使いづらいとしか思わなかった。今回フォイルで新スペシャルのスミナガシート使ってみたさにやってみたら意外と面白かった。じゃあウルショが使える無印はもっと強くね?と思ったら案の定強かった。スプラ2当時よりも立ち回りが変わっていたのか、使いづらさは感じなかったどころか、スシから乗り換えるか?と思ったほど。塗りは若干落ちるが気にならない程度。

 

想像よりも弱かったブキ

第5位:ワイドローラー系統

カーボンローラーの悪いところが全面的に出るブキ。「なんで今のが50%やねん!任天堂!。みてるかイカ研究員!」と叫んだ数は数知れず(50%とかそういう次元ではは無い)。ローラー故、極端にリザルトが悪くなることはないが、上述の通り確定1発で倒せないことが多々あったため「カーボンローラー/スプラローラーでよくね?」としか思えなかった。

 

第4位:ジムワイパー系統

ブキの強さとしてはトップランクなんだろうけど、僕には扱えなかった。時折tier1の自覚を見せてくれたが、誰にでも扱えるブキではない。このブキに関しては強さを見出せなかっただけで、対面したら厄介であることは間違いない。でも僕はもう使うことはないかな…

 

第3位:ソイチューバー系統

おそらく使いづらさ1位になると思ってたブキ。それでもこの順位に留まったのは、後半の方で半チャで倒せるようなコツを掴んだからである。使いこなせば戦える感じはあったが、どうしても「スプラチャージャー/リッターで良いわ」感が拭えなかった。何なら射程も短めなのでスクイックリンで良いわとも思った。色々残念なブキ。

 

第2位:ケルビン

これは意外に思ったが、理由としてはジムワイパーと同じような理由。僕には使えなかった。最大限の性能を出すにはスライドが大前提で、他のスライドブキとはかなり使い勝手が異なった。射撃レートも低めと言うこともあってあまり合わなかった。(あるけみーは射撃レートが高めの武器が好き)

今回のチャレンジで1番連敗したブキ。

 

第1位:ドライブワイパー系統

ジムワイパー使えないんだからドライブワイパー使えるわけないだろ!今回挙げたブキで一番使い方が分からなかった。しんどみの翁。ジムが縦切り横切りで倒せるんだから、それと比較してしまうと下位互換になりがち。強いていうと塗りは強いけど、だったら他ブキでいいなぁとなってしまった。

 

というわけで勝手にランキングしましたが、ブキは好きなもの使えば良いと思うよ。でもな、ペナアップリッターだけは持ち込まないようにしよう。おじさんとの約束だよ。

今年の振り返りと来年のTry

今年もこの時期がやってきました。片手でポケモンSVの金策をやりながら書いてます。

さて今年の振り返り。目標は下記の通りでした。

fieldpaddy.hatenablog.com

 

・月に1冊以上の読書をする(技術書以外で)○

比較的できていたと思います。若干小説系は読めてなかったのが心残り。

 

・週3回以上の運動(1回10分〜15分程度) ×

これはマジでやってない。時間を捻出できなかった。代わりと言っては難だが、隣駅で下車して歩いて帰ることもやった。ただやはり全然できていない。

 

・継続的な技術の習得と資格取得 ○

今年取った資格は、

です。特に応用情報はようやく再挑戦して取ることができました。

 

・月1回以上のアウトプット △

ちょっと中途半端な出来でした。Qiitaで投稿できたのはいい経験でした。

 

来年の目標は下記の通りです。

AWS認定全冠達成

残り4つです。後1年で有効期限が切れるものもあるので今年しかチャンスがないので取りに行きたいと思います。

 

・リーダーとしての知識、素質を身につける

難しいと思います。開発チームを纏める立場として必要なスキルを身に着けたいと思います。

 

とりあえず目標は2つにしておいて、目標にできることが増えたら追加でやっていきたいと思います。

 

さて、ことしも激動の一年でしたが、公私ともに大変お世話になりました。来年も何卒よろしくおねがいします。

ワールドカップのメンバー予想してみた

気がついたら明日で11月ですって。

 

明日、サッカーワールドカップの日本代表メンバー発表ということでほぼ代表戦しか観てないニワカがメンバー予想してみた。

 

GK

確定 権田、シュミット

予想 川島

この2人は確定だと思う。で、残り一枠なんですが、実績や出場試合数見たら川島だけど、GKの平均年齢上がるなあって感じ。若手の谷、大迫辺り呼んで良い気はするけど、ここでは川島と予想。

 

DF

確定 吉田、冨安、酒井宏、長友

予想 板倉、伊藤、谷口、中山、山根

確定は4バックの先発はこうだろうな、という4人。予想の板倉は怪我の程度が気になるが、ほぼ確定。伊藤、谷口、中山あたりまでは選ばれそう。最後の右サイドバック枠で山根を選んでみたが、冨安、長友あたりが右サイドバックできるので、微妙。ターンオーバー考えるとサイドバック選んでおきたいが…。山根だけ自信なし。

 

MF/FW

確定 遠藤、守田、鎌田、三笘、伊東

予想(MF) 久保、堂安、田中碧、相馬、原口

予想(FW)   前田、大迫、古橋、上田

明日もMF/FWという発表の仕方をするかは分からないが、まあ最近こういう発表だったしこれで予想。

確定枠の5人は選ばないと予選敗退確定レベル。というか今まで何を見てたんだって話。

久保も特に最近のパフォーマンスみればほぼほぼ確定だと思う。堂安、田中碧、相馬、原口は分からんかった。南野と入れ替わるかもしれんが、正直南野を入れたい気がしなかった。

FWはマジで分からん。抜きん出たストライカーがいない。強いて言えばこないだのアメリカ戦で良かった前田、こないだ2点決めてた上田はほぼ確定の枠。古橋は代表にあってないけど選ばれそう。大迫は怪我明けのパフォーマンスをどう評価するか次第。

 

以上26人で、正直サプライズなさそうと思っているが、山根の枠が長谷部になったらめちゃくちゃ面白いなって思った。まあ日本代表引退宣言してた気がするので、正直ありえないかな。

 

26人全部当ててたら誰か奢ってください。

 

読んだ本、要約シリーズ『エッセンシャル思考』

2022年ブログ初投稿です。アウトプットを重要視する年とかいいつつ、半年たってもアウトプットが出てこないサボり魔とは僕のことです。

 

本日は今年に読んだ本の要約シリーズということで『エッセンシャル思考』という本の要約です。簡単に言ってしまえば、人生の無駄を省こう!的なお話です。全20章それぞれでまとめてみました。

PART1 エッセンシャル思考とはなにか

より多くの仕事をこなすものではなく、仕事のやり方を変えるもの。そのためにはものの見方を大きく変える必要がある。

エッセンシャル思考になるためには「やらなくては」「どれも大事」「全部できる」といった思い込みを克服しなくてはならない。

「やらなくては」→「やると決める」

「どれも大事」→「大事なものはめったにない」

「全部できる」→「何でもできるが、全部はやらない」

この3つの真実が本当に大事なことを見極め、仕事や人生において最高のパフォーマンスを発揮する事ができる。

 

第1章 エッセンシャル思考と非エッセンシャル思考

  • エッセンシャル思考は「より少なく、しかしより良く」を追求する生き方。「今、自分は正しいことに力を注いでいるか?」と絶えず問い続けるのがエッセンシャル思考の生き方。エッセンシャル思考は、より多くのことをやり遂げる技術ではない。正しいことをやりとげる技術だ。自分の時間とエネルギーをもっとも効率的に配分し、重要な仕事で成果を上げるのがエッセンシャル思考の狙い。
    →エッセンシャル思考は自分の力を最大限の成果につなげるためのシステマティックな方法。

考え方:「みんな・すべて」→「より少なく、しかしより良く」

行動 :「やることをでたらめに増やす」→「やることを計画的に減らす」

結果 :「無力感」→「充実感」

  • 自分で優先順位を決めなければ、他人の言いなりになってしまう。
  • 優秀な人ほど成功のパラドックスに陥り、方向性を失ってしまう
    • 今の世の中は、選択肢が多すぎる
    • 今の世の中は、他人の意見がうるさすぎる
    • 今の世の中は、欲張りの時代
  • 方向性を見失わずに、必要なものと不要なものを区別するには、「評価(見極め)」し、「捨て」、「実行(仕組み化)」することが大事

 

第2章 選択

  • 選ぶ能力は誰にも奪えない。ただ、本人が手放してしまうだけだ。

「やらなくては」→「これをやろう」

「選ぶ余地がない」→「自分で選び取る」

 

第3章 ノイズ

  • エッセンシャル思考の人はたっぷりと時間を掛けて選択肢を検討する

「大多数の物事が重要だと考える」→「大多数の物事が不要だと考える」

「どの選択肢も平等に扱う」→「決定的に重要なことだけをとる」

 

第4章 トレードオフ

「両方できるさ」→「何を取り、何を捨てるか」

「どうすれば全部できる?」→「何に全力を注ぐ?」

 

PART2 見極める技術

  • 忙しく動き回ることを有能さの証だと思っている人は、考えたり眠ったりする時間をなるべく減らそうとする。
  • しかし、立ち止まっている時間こそが生産性を高めるための特攻薬

第5章 孤独

  • 集中するためには、集中せざる得ない状況に自分を置くしかない
  • 毎日5分でも、忙しい日常から離れ、自分だけでいられる時間を確保しよう

「忙しくて何も考える余裕がない」→「考えるための余裕をつくりだす」

第6章 洞察

  • 現代の職場はカオス→本質を掴み取らなくてはならない
    • 日記をつける
    • 現場を見る
    • 普通を知り、逸脱を探す
    • 問題を明確にする

「声の大きい意見に反応する」→「ノイズのなかのシグナルを探す」

「話のすべてを聞こうとする」→「語られないことに耳を傾ける」

「情報の渦に飲み込まれる」→「情報の本質を掴み取る」

 

第7章 遊び

  • 遊びはエッセンシャル思考に不可欠である
    • 選択肢を広げてくれる
    • ストレスを軽減してくれる
    • 脳の高度な機能を活性化する
  • 遊びは本質を探求するのに役立つだけではなく、それ自体がどこまでも本質的である

「遊びを軽視する」→「遊びを重視する」

「遊びは時間の無駄だと思う」→「遊びが不可欠だと知っている」

 

第8章 睡眠

  • 現代人の最優先課題は、優先順位づけの能力をキープすること
  • 睡眠不足だと優先順位の見極める能力が落ちてしまう
  • まとまった睡眠が取れないのであれば、昼寝も有効

「もう1時間睡眠時間を削れあb、もう1時間仕事ができる」→「もう1時間眠れば、数時間分の生産性が手に入る」

「眠るのは根性なしだ」→「優秀な人はよく眠る」

「眠ると怠け者になる」→「眠ると創造的になる」

「睡眠のせいで仕事量が減る」→「睡眠は仕事の効率を高めてくれる」

 

第9章 選抜

  • 絶対にイエスだと言い切れないなら、それはすなわちノーである

「何にでもイエスという」→「上位10%にだけイエスという」

「「みんながやっているから」やる」→「「まさに自分の求めていることだから」やる」

 

PART3 捨てる技術

  • 仕事や人生の決定打となるブレイクスルーは、不要なものを切り捨てることから始まる

第10章 目標

  • 目的が明確でないとき、人はどうでもいいことに時間とエネルギーを浪費する
    • 社内政治が蔓延する
    • 何でも屋になる
  • 具体的で魅力的な本質目標を決める
    • 言葉にとらわれない(形より中身が大切)
    • 達成をどのように判断するか

「価値観やビジョン、ミッションステートメント」→「具体的かつ魅力的な戦略」

「具体的だが、人の心を動かさない四半期目標」→「意味があり、心に残る本質目標」

「価値観はあるが、それを実行するための行動規範がない」→「一つの決断によって、その後のあらゆる決断を不要にする」

 

第11章 拒否

  • 絶対にやるべきこと以外の全てに対して上手に「ノー」ということが大切

「周囲の期待とプレッシャーに負けてイエスという」→「きっぱりと上手にノーという」

「何でも引き受ける」→「本当に重要なことしか引き受けない」

 

第12章 キャンセル

「こんなに金をかけたのに、今更やめられない!」→「もしもまだ1円も払っていないとしたら、今からこの企画に投資するだろうか?」

「やり続ければ、いつか報われるはずだ」→「今これをやめたら、何に時間とお金を使えるだろう?」

「失敗を認めたくない」→「すすんで損切りをする」

 

第13章 編集

  • 編集の4原則
    • 削除する
    • 凝縮する
    • 修正する
    • 抑制する

「良くすることは、何かを付け加えること」→「良くすることは、何かを削ること」

「あらゆる細部に愛着がありすぎる」→「不要な細部は冷徹に切り捨てる」

 

第14章 線引き

  • 境界線を引くことで自分の時間を守り、他人からの干渉を防ぐ

「境界線は自分の力を制限するものだ」→「境界線を引くことで本当の力が発揮できる」

「境界線はきゅうくつだ」→「境界線は自由を生む」

「毎回ノーを言うのに苦労する」→「ノーと言わなくてもいいように予めルールを設定する」

 

PART4 しくみ化の技術

  • 人は楽をしようとする生き物であるため、何の苦労もせずにスムーズに正しい行動ができるようにしておくことが必要

第15章 バッファ

  • 世の中に確実なことはないため、何が起こってもあわてないように予め備えておいたほうが良い

「最善のケースを想定する」→「最悪の事態を想定する」

「土壇場にならないと頑張らない」→「準備と計画に全力を注ぐ」

 

第16章 削減

  • 仕事を減らすことでより多くを生み出す
    • 目指すことを明確にする
    • ボトルネックを特定する
    • 邪魔なものを取り除く

「応急処置を積み重ねる」→「本当の障害を取り除く」

「仕事が増える」→「成果が増える」

 

第17章 前進

  • 重要なことをやりとげるために、最低限意味のある進歩はなにか?と考える
  • 「遅く大きく」ではなく、「早く小さく」を心がける
  • 小さな達成を繰り返すことが見えるように形にする

「多くを望み、得るものは少ない」→「小さく始めて、大きな成果を得る」

「派手な勝利を追い求める」→「地味でも着実に勝ちに行く」

 

第18章 習慣

  • 正しい習慣がクリエイティビティを生む
    • 行動を引き起こすトリガーを知る
    • 難しいことから手を付ける
    • 習慣づくりはひとつずつ

「火事場の馬鹿力に期待する」→「正しい習慣を通じて自然に達成する」

「重要なことをやるのは例外的」→「重要なことをやるのが普通の状態」

 

第19章 集中

  • 過去や未来にとらわれず、今この瞬間に没頭する
  • マルチタスクではなくマルチフォーカスが真の敵。人間は一度にひとつのことしか集中できない
  • 「今、何が重要か」を考える
  • 未来を頭の中に抱えない
  • 優先順位をつける

「過去と未来に引き裂かれている」→「現在に集中している」

「機能や明日の問題について考える」→「目の前の問題を考える」

「未来への不安や過去の失敗を思い悩む」→「今を楽しむ」

 

第20章 未来

  • 考え方が心の底まで染み込んだとき、それは自分を内側から変える力となる
  • 人生の分岐点に立った時、「本当に重要なことはなにか?」と自分に問う

 

ここからは感想。本は読んだだけでは意味がない、というのはよく言われていることです。なので今回はこうやって要約をしてみました。もっと言えば、実践していくことが大切だと思います。出来ていること、出来ていないことありますが、一つでも実践出来るようになれば良いなと思いました。

また別の機会に読んでる本コーナーを投稿したいですね。