😸

MA-S120/LA,GLA で計測したアナログデータをSORACOM Harvestに送信する(ステップ2:cronを使った定期送信)

2023/08/29に公開

やりたいこと

Century Systems社のルーターについているアナログ入力インターフェースに入力したセンサからの信号(電圧/電流)値を取得して、SORACOM Harvest Dataに送信する方法をご紹介します。
今回はステップ2ということで、ステップ1の末尾この後の流れとして書いた、IoTデータとして定期送信する方法について記載します。

つまり、

ステップ1で確認したという一連の動作を、

  • センサデータを取得
  • 生データから工学値変換(bcコマンド)
  • httpでデータをPOST(curlコマンド)

ステップ2では以下の設定をすることで定期的に送信する方法を確認していきます。

  • 1分に1回定期的に送信(cron)
  • エラーが発生した場合にはsyslogに記録(loggerコマンド)
  • 設定した内容を永続化させる

前提条件

このシリーズではIoTやLinuxにまだあまり馴染みがない方向けに以下の前提で進めます。
LinuxやIoTに詳しい方にとっての最適解となっていませんのでご容赦ください。

  • 出荷時の状態から実施できる方法
    • 基本的にshellコマンドで実施する
      • 追加のパッケージインストールやOSのカスタマイズを実施しない
    • ファイアウォールの設定を変更しない
      • USBのシリアルコンソールからの操作のみとする
      • SSH/SCPは使わない
  • SORACOMに接続している
    • SORACOMのサービスを活用する

準備

このブログではステップ1の内容を実施・理解していることを前提とします。わからないことがあったら適宜戻って確認しましょう。

設定内容

まずはShell Scriptとcron の設定を見ていきます。

Shell Script

Shell Scriptとは

主にLinux(UNIX)で実行する一連のコマンドを書き連ねたプログラムです。
ステップ1では

  • センサデータを取得(catコマンド)
  • 生データから工学値変換(bcコマンド)
  • httpでデータをPOST(curlコマンド)

というコマンドを組み合わせてデータが送信できることを確認したと思います。これらの一連のコマンドを書き連ねてまとめて実行できるようにしたのがシェルスクリプトです。
Windowsでいう、バッチファイルのようなものです。

Shell Script例

前回確認したコマンドにエラーハンドリングを追加し、エラーが発生した場合にはloggerコマンドでsyslog(/var/log/syslog)に記録する処理を追加しました。
詳細はコードスニペット内にコメントで記載したので、前回のコマンドと見比べながら動作を確認しましょう。

本ブログでは、/rootというディレクトリにupload_sensor_data_to_harvest.shという名前で置くことにします。
この後のcronの設定と整合がとれていれば置き場所は自由です。管理しやすいように適宜変更してください。
ファイルパス:
/root/upload_sensor_data_to_harvest.sh

#!/bin/bash

# scaleという変数にcatコマンドで取得したscaleの値を代入する
scale=`cat /sys/bus/iio/devices/iio\:device1/in_voltage_scale`
# cat コマンドの実行失敗時にエラーメッセージを出力し、スクリプトを終了する。
if [ $? -ne 0 ]; then
logger -p user.err "Error: Failed to read scale value."
exit 1
fi

# rawという変数にcatコマンドで取得したAD変換値を代入する
raw=`cat /sys/bus/iio/devices/iio\:device1/in_voltage0_raw`
# cat コマンドの実行失敗時にエラーメッセージを出力し、スクリプトを終了する。
if [ $? -ne 0 ]; then
logger -p user.err "Error: Failed to read raw value."
exit 1
fi

# 電圧の値を(scale x raw + 2500) / 1000 [V]で計算する。
# 小数の掛け算を行うため、bcコマンドで実施する。
voltage=`bc -l <<< "($scale*$raw+2500)/1000"`
# bc コマンドの実行失敗時にエラーメッセージを出力し、スクリプトを終了する。
if [ $? -ne 0 ]; then
logger -p user.err "Error: Failed to calculate voltage."
exit 1
fi

# curlコマンドでクラウドにデータを送信する
# -s フラグは "silent" モードを有効にし、 -w "%{http_code}" はHTTPステータスコードを返す。これにより、HTTPステータスコードを response 変数に格納してエラーハンドリングで使用する。
response=$(curl -s -w "%{http_code}" -X POST http://uni.soracom.io:8888/ \
-H "Content-Type:application/json" \
-d '{
"voltage": '"${voltage}"'
}')

# curlの実行結果をチェックする
# curl コマンドのHTTPステータスコードが200、201(成功)いずれでもでない場合にエラーメッセージを出力し、スクリプトを終了する。
if [ "$response" -ne 200 ] && [ "$response" -ne 201 ]; then
logger -p user.err "Error: Failed to upload data to cloud, HTTP status code: $response"
exit 1
fi

※ if文はif [条件式] ;then (処理) fi といった構文で記載されます。
※ 条件式の中に登場する$?はひとつ前に実行したコマンドの結果を格納する特殊変数です。コマンドが正常に実行された場合は0、その他の場合は他の値が格納されます。

cron

cronとは

こちらも主にLinux(UNIX)で使われる、設定したスケジュールに従って自動的にコマンドを実行するための仕組みです。
Windowsでいう、タスクスケジューラのようなものです。

cronの設定例

今回のcronの設定は/etc/cron.d以下にupload_sensor_data_to_harvestというファイル名で保存することにします。
ファイル名は

ファイルパス
/etc/cron.d/upload_sensor_data_to_harvest

記載内容は以下の通りです。

*/1 * * * * root /root/upload_sensor_data_to_harvest.sh > /dev/null 2>&1

※ 一般的には`crontab -e'で設定することもありますが、センチュリーシステムズのウェブサイトに以下の記載があったため、今回は利用しません。

※cron設定ファイルの書式は以下の通りです(/etc/crontabに記載されています)。

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name command to be executed

*はすべてを選択する場合に使用します。
今回の設定例ではminuteの設定を*/1としましたが、これは1分間隔で実行する場合の設定例です。例えば5分間隔で実行する場合は、*/5と設定します。

設定手順

Shell Scriptとcron設定の具体的な内容が決まったら、設定していきましょう。
※繰り返しますが、ssh/scpやコマンドラインエディタ(vi,nanoなど)が使える方はお好みの方法で実施しましょう。

Shell ScriptをMA-S120に送り込む

メモ帳でShell Scriptを作成する

メモ帳を開きます。

先ほどのシェルスクリプトの内容をクリップボードにコピーし、

貼り付けます。

名前(upload_sensor_data_to_harvest.sh)をつけてわかりやすいところ(デスクトップなどどこでもOKです)に保存します。

保存した場所にファイルができていればOKです。

Shell ScriptをSORACOM Harvest Filesに置く

MA-S120が所属しているSIMグループにSORACOM Harvest Filesが有効になるように設定します。

ファイルをアップロードします。
左上のメニューから、

データ収集・蓄積・可視化の「SORACOM Harvest Files」を選択し、

「アップロード」ボタンをクリックします。

ファイルをアップロードのモーダルに先ほど作ったファイルをドロップまたは選択すると、「アップロード先のフルパス」というフォームが現れます。
ここに保存先を指定して(今回は/script/upload_sensor_data_to_harvest.shにしてみました)、アップロードをクリックします。

完了後、以下のように表示されればOKです。

MA-S120から SORACOM Harvest DataにアップロードしたShell Scriptをダウンロードする

PCとMA-S120をUSBコンソールで接続し、Tera Termを開いてrootでログインします。

harvest dataにアップロードしたファイルをMA-S120 から取得します。

curl http://harvest-files.soracom.io/script/upload_sensor_data_to_harvest.sh > upload_sensor_data_to_harvest.sh

※http:// から始まるURLは先ほどのSORACOM Harvest Dataの画面に表示されていた「SORACOM Air用 URL」です。

実行結果

lsコマンドを実行すると
upload_sensor_data_to_harvest.shというファイルが生成されていることが確認できます。

このシェルスクリプトはこのままでは実行できないので、微修正をかけていきます。

  1. Windowsのメモ帳(notepad)で編集したものであるためLinuxと改行コードが異なっているため、改行コードを変更します。
sed -i 's/\r//g' upload_sensor_data_to_harvest.sh

※ windowsの改行コードはCRLF(\r\n)で、LinuxはLF(\n)
※ sedコマンドの意味はupload_sensor_data_to_harvest.shというファイルを直接編集して、内部に含まれるすべての\rを除去するコマンドになっています。
このコマンドの実行後の出力は特にありません。

2.実行権限を付与します。

chmod +x upload_sensor_data_to_harvest.sh

ls -lコマンドを実行して、-rwxr-xr-xとなっていればOKです。

実行結果

この時点で正しく実行可能なShell Scriptになっていることを以下のコマンドを実行して確認しましょう。

./upload_sensor_data_to_harvest.sh

SORACOM Harvest Dataに送信したデータが入っていれば成功です。

cronを設定する

cron設定ファイルを作成する

Shell Scriptを1分間隔で実行する設定を/etc/cron.d/upload_sensor_data_to_harvestに書きます。

中身が1行のファイルなので echoコマンドとteeコマンドでいきます。

echo "*/1 * * * * root /root/upload_sensor_data_to_harvest.sh" | tee /etc/cron.d/upload_sensor_data_to_harvest > /dev/null

実行後、

ls -l /etc/cron.d

で、upload_sensor_data_to_harvestというファイルができていることが確認できます。

このファイルの中身を確認します。

cat /etc/cron.d/upload_sensor_data_to_harvest

ファイルの内容が表示され、設定したかった内容が記載さえていることが確認できると思います。

実行結果

cronを再起動する

新たに作成した設定を有効化するため、cronを再起動します。

systemctl restart cron

暫く経ったらcronの稼働状況を確認します。

systemctl status cron

実行結果から(root) CMD (/root/upload_sensor_data_to_harv>が見つかればOKです。
実行結果

ついでに、SORACOM Harvest Dataの様子も見ておきましょう
データが1分間隔で来ていたら成功です。

MA-S120を再起動する

ここで安心して、電源をブチっとやってしまうとせっかくデバイス内に保存したShell Scriptのファイルとcron設定ファイルが消えてしまいます。
MA-S120はシステムを電断から保護するため、ファイルシステムへのアクセス(読み書き削除)は直接行われておらず、起動中はRAM上で変更が行われています。
シャットダウンシーケンスを正しく実行することで、RAM上のファイルシステムに記録されたデータを内部のディスクメモリに永続化するのでコマンドを使って再起動します。

reboot

再起動後もSORACOM Harvest Dataにデータが1分間隔で来ることが確認できればステップ2は完了です。

次のステップ

無事1分間隔でにセンサデータを送れるようになりました。
ひとまずこれでもいいのですが、あと一歩デバイス側で頑張ったほうがよいことがあります。

今回のデータ送信のShellScriptでは、curlコマンドが失敗した場合には失敗したごとがsyslogに記録されるのみで、送信に失敗したデータを再送することはなく、送信に失敗したデータの値が何だったのか後から知ることもできません。

curlコマンドはさまざまな理由で失敗します。電波状況などのLTE通信の不調、TCP/IPのパケットロス、サービスの一時的な障害。移動体であれば常にキャリアのサービスエリア内にいるとも限りません。

ステップ3では、このような場合に備えて送信に失敗したデータを後で再送する仕組みについて考えたいと思います。

GitHubで編集を提案

Discussion