あるけみーの小屋~204 No Content~

趣味の話とか色々

雑記

普段はQiitaが主戦場だけど、今回は個人的な話が多めなので個人ブログで。

 

◼️目標関連

今年度はいくつか目標を立てたので中間振り返り。(ちょっと早いけど)

 

・社外登壇2回以上

5/10に今年度初社外登壇。オフラインでの社外登壇は実は初めてだったりする。ネタ自体はQiitaにも投稿してたので時短で作った。オンラインの時とはまた違う感覚だったけど、楽しかった。またどこかにお邪魔して話したいな。

speakerdeck.com


・毎月Qiita投稿

今のところ継続中。ネタ自体は大量にあるものの、形にする時間がなくてなかなかしんどみ。

 

↓こんな感じでメモ帳に書いてる

f:id:fieldpaddy:20250513164823p:image


・ネスペ取得

4/20に試験は受けた。午前Ⅱは自己採点して合格ラインは超えてた。午後問題は解答速報とか眺めてみたけど、なんとも言えない。7月の合否発表を待つ。

 

AWS認定全冠維持

今年新しいやつが追加されるかは分からない。もし去年と同じであればANSだけ6月に期限切れになるので、いつか受ける。


・何か作って公開する

未着手。一個アイデアは思い浮かんだけど、既にやってる人いるだろなーという感じ。車輪の再発明はやりたくないのでまずは市場調査をやる。


・子供と接する時間を減らさない

頑張ってるつもり。これ、定量的な評価できないな...


・プレーリーカード作る

作った。


・健康を意識した生活をする

頑張ってるつもり。魚食べたり、野菜も意識して食べる様にしてる。通勤時に1駅分は歩いてるけど、それ以外の運動がどうしてもできない。健康診断の結果見て今後の活動考える。

 

電気通信主任技術者(伝送交換)科目合格

期中追加目標。来年1月目標にしてたけど、3科目まとめて取るのがしんどそうだったので法規だけでも最低限取って、あわよくば電気通信システムも取りに行く。

 

・モンハンを積まない

ストーリーはクリアしたし、ハンターランクも65くらいになった。ランク100くらいまではやりたいけど、ここらが落とし所な気がする。ここまでやってれば積んだことにはならないでしょう。というかゲームに割く時間が一番最初に削られる。

 

 

◼️キャリア関連

自身の思考整理も兼ねて。

※ここで言うエンジニアとは、最新技術を吸収していくソフトウェアエンジニアなどを指してます

 

最近の大きな悩み。コミュニティの中で知り合った人や、会社の上司や他部署の部長に話を聞いてもらったり。今の本部には結構知ってる人が多いので相談には困らない。人脈って大事だなぁ。

 

積極的に外部で話してるわけではないけど、将来はエンジニアじゃなくてリーダー職を目指してる。理由はいくつかあるけど、ライフスタイルの変化によるものが大きい。

 

歳を取ると新しいことが覚えられなくなるとはよく聞く。これはエンジニアにとっては致命的で、どんどん取り残されてしまうのかなと思った。AI時代にマネジメント職がどれほど必要とされるかは分からないけど、10年後、20年後を考えた時に食っていける可能性があるとしたらエンジニアよりはマネジメントなのかなと思った。

 

たぶん、キャッチアップとかしなくてもそこそこの事はできるかもしれないけど、僕が描くエンジニアの理想像とはかけ離れてしまう。あと、金銭面で今よりは稼ぐ必要があると思ってる。転職も選択肢だが、子供が小さい中ではかなりのリスク。それに個人的には職場に不満はないし、給料面も今困ってるという話ではなく、例えば子供が私立の高校・大学に行ったらどうなる?その時お金が足りないってなったらどうする?ということを考えての話。給料はそれこそ転職でもしない限り劇的に変わるものではないので今のうちからできることをコツコツやるしかないのだ。

 

なので最近は技術系であればアーキテクト関連の本を漁ったり、マネジメント系の本を読み始めてる。手を動かす系は極力控えめにしていて、やらなきゃエンジニアじゃねぇ!みたいな内容は(もちろん時間が許す限りの範囲で)やるようにしている。PMBOKはそのうち確認したい。

 

元々はエンジニアとして生きていくのが難しくなるから、といった理由でリーダー職を視野に入れていたが、最近は少しずつ考えが変わる様になった。僕はエンジニアとしては平凡なので、優秀な人にどんどん手を動かしてもらった方が会社や社会にとってはトータルで価値が出るのかなと思った。

 

そういった意味で、「エンジニアが楽しく働ける環境を創る」「社内外の人とコミュニケーションを取ることの重要性を説く」ことがリーダーとしての目標なのかな。後者については社外コミュニティの運営を通して、その良さを伝えていければ。

 

ちなみに、リーダー職と専門職の転換はできると聞いているので、もし頭の衰えを感じなかったらその時はまた考える。(リーダーが向いてないと気づく可能性もあるし)

 

いずれにせよ、後悔しない道を選択するんじゃなくて、選択した道で後悔しない努力を心がけたい。間違ってたら修正すれば良いだけ。

 

ただまあ選択肢は多いに越したことはないので、選択肢を狭める選択はしたくない。かいのカセキとこうらのカセキ、どちらか一つじゃなくて両方ゲットする方法を考えたいものである(発想がロケット団)。

 

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人全部当ててたら誰か奢ってください。