Armadilloフォーラム

armadillo上でのcronについて

suke_suta

2024年9月20日 16時35分

お世話になります高橋です

armadillo-Iot A6 でセンサーで収集したデータをcronを使用して出力したいです
プロトコルAとプロトコルBがあり前者が10分おきに起動し後者が1分おきに起動します
起動させるデータをarmadilloに移し
LIENEYEで確認してみたところ何も出力されていませんでした

armadillo内でのcronの動きを確認したところ添付したcronログ.png のようになっていました、エラーの原因はどこにあるのでしょうか?

また、コマンドはこの画像のような配置で良いでしょうか?

ファイル ファイルの説明
cronログ.png cronにエラーが出てしまっています
cronコマンド.png
コメント

at_shota.shimoyama

2024年9月24日 16時49分

下山です。

crontabの時間指定部分は問題ないように思えますが、コマンド部分については、

/root

とありますが、/rootディレクトリが既にカレントディレクトリのはずであるため、おそらく不要です。
また、cronは添付いただいた画像のとおり、cronに関係するログは表示されますが、実行されるコマンドからのエラー等は表示されません。
例えば、cronログ.pngには、

(CRON) error (grandchild #857 failed with exit status 12)

といったエラーが表示されていますが、このエラーは実行しているコマンド「/root && python3 xxxxx-b.py」から来るエラーのはずです。
しかし、それが具体的にどのようなエラーなのかは表示されません。
どのようなエラーなのかを表示させるためには、コマンドの後ろに

> yyyyy.log 2>&1

とつけて標準出力とエラー出力をファイル(yyyyy.log)として出力させるように手動で設定する必要があります。

ですので、次のように変えてみてください。

*/10 * * * * python3 xxxxx-a.py > a.log 2>&1
* * * * * python3 xxxxx-b.py > b.log 2>&1

もしこれでcronのログにエラーが現れる場合、a.logまたはb.logの中身をcatで確認してみてください。エラーの詳細が記載されているはずです。

よろしくお願いします

suke_suta

2024年9月25日 10時01分

高橋です、ありがとうございます

ログを確認できるようにしてみた所

Sep 25 09:14:00 armadillo CRON[525]: (root) CMD ([526] cd /root && python3 xxxxx-b.py b.log2&>1)
Sep 25 09:14:00 armadillo CRON[525]: (root) END ([526] cd /root && python3 xxxxx-b.py b.log2&>1)
Sep 25 09:14:28 armadillo systemd-timesyncd[193]: System clock time unset or jumped backwards, restoring from recorded timestamp: Wed 2024-09-25 09:14:25 JST
Sep 25 09:14:28 armadillo cron[237]: (CRON) INFO (pidfile fd = 3)
Sep 25 09:14:28 armadillo cron[237]: (CRON) INFO (Running @reboot jobs)
Sep 25 09:22:12 armadillo systemd-timesyncd[193]: Synchronized to time server for the first time 202.181.103.212:123 (2.debian.pool.ntp.org).

このようなログが表示されました、システムクロックの時刻の設定が解除されるか逆方法にジャンプという内容が出ていますが
これはアルマジロの設定の問題なのかプログラム内の問題なのかどちらでしょうか?

よろしくお願いします

at_shota.shimoyama

2024年9月25日 10時45分

下山です。

添付されたcronのログを拝見したところ、crontabでコマンドが正しく設定されていないように見えます。

cd /root && python3 xxxxx-b.py b.log2&>1

と設定されておりますが、次のことに注意して、

python3 xxxxx-b.py > b.log 2>&1

と指定してください。
1.「xxxxx-b.py」と「b.log」の間に、「 」(スペース)と「>」と「 」(スペース)が必要です
2.「b.log」と「2&>1」の間に、「 」(スペース)が必要です
3.「2&>1」の「&」と「>」が逆になっています、「2>&1」と変えてください
4.「cd /root && 」は/rootディレクトリに移動するコマンドですが、移動しなくともすでに/rootディレクトリにいる状態のはずです。なにか「cd /root && 」と付けなければならない事情等がおありでしょうか?もしそうでなければ「cd /root && 」はひとまず削除してみてください。

上記の通りに設定されていれば、/rootディレクトリにb.logというファイルが生成されるはずです。

よろしくおねがいします

suke_suta

2024年9月25日 11時30分

高橋です

申し訳ありません、修正しb.logの内容を確認した所

root@armadillo:~# cat /root/b.log
Traceback (most recent call last):
  File "upload-b.py", line 1, in <module>
    import serial
ModuleNotFoundError: No module named 'serial'
 

このように表示されたので、bのプログラムに問題があるのかもしれません

もう一つお聞きしたいのですが

今の状態でArmadilloをプロトコルアナライザーに接続すれば、何かしらの出力は確認できるという認識でよろしいですか?

at_shota.shimoyama

2024年9月25日 12時06分

下山です。

修正していただきありがとうございます

添付いただいたログに記されているエラーはPythonから出力されているものです。
ですので、現状ではcronに問題はなく、ご自身が用意されたPythonプログラムに対するデバッグが必要になります。

このような場合は、Pythonから出力されているエラーですから、例えばログに記されているエラーの名前「ModuleNotFoundError」と「Python」というキーワードを合わせて「Python ModuleNotFoundError」とインターネット上で検索すれば豊富な情報が出てきます。今後のご参考になれば幸いです。

また、Pythonのエラーの場合は

File "upload-b.py", line 1, in <module>
 import serial
ModuleNotFoundError: No module named 'serial'

のように、どのファイル(upload-b.py)のどの行(line 1)のどのコード(import serial)でどのエラー名(ModuleNotFoundError)で具体的にどのようなエラー(No module named 'serial')が発生しているのかを分かりやすく表示してくれます。

今回の場合は1行目の時点でエラーが発生していますので、今の状態でArmadilloをプロトコルアナライザーに接続しても出力は確認できないと思います。

また、「No module named 'serial'」というエラーは、「import serial」の部分でserialというpythonのモジュールをインポートしようとしたけど、serialというpythonモジュールがありませんよというエラーになります。

これを解決するためにはserialという名前でインポートできるpythonのライブラリをaptかpipでインストールすればいいはずです。
おそらく

pip install pyserial

と実行してpyserialをインストールすればひとまず解決すると思いますが、あらかじめインストールしておかなければならないPythonパッケージのリストや、インストール手順などの詳細な情報がプログラム作成時点で残っていた場合はそちらに従ってください。

よろしくお願いします

suke_suta

2024年9月25日 15時00分

高橋です

と実行してpyserialをインストールすればひとまず解決すると思いますが、あらかじめインストールしておかなければならないPythonパッケージのリストや、インストール手順などの詳細な情報がプログラム作成時点で残っていた場合はそちらに従ってください。

pyserialをインストールし Version: 3.5 があることを確認しました
その後に b.log を確認するとやはり同じエラーが出力されていました、これはまだインストールしただけで実装できないという事ですか?
手元の資料ではPythonとPython3以外にインストールするものは書かれておりませんでした

よろしくお願いします

at_shota.shimoyama

2024年9月25日 16時11分

下山です。

申し訳ありませんがこちらでは再現できませんでした。

本来はインストールしただけで充分なはずなのですが、pyserialをインストールしているのにも関わらず同じエラーが出力されるということは、Pythonがpyserialがどこのディレクトリにいるのかを把握できていないということだと思われます。
原因を調べるために次のことを行っていただけますでしょうか?

1.xxxxx-b.pyの先頭に、以下の3行を追加してみた上で、b.logの内容を添付してください。

import sys
import pprint
pprint.pprint(sys.path)
(元々の1行目)import serial

これは、sys.pathをb.logに表示させるための行です。
Pythonは「import xxxxx」のインポート文が呼び出されると、sys.pathという変数に記載されているパスの中からxxxxxというディレクトリを探すことで、インポートします。

2.次のコマンドの結果を添付してください

python3 -m pip show pyserial

この結果のLocationというところに、pyserialがどのディレクトリに位置されているのか表示されます。

1のsys.pathの中に、2のLocationが含まれているかどうかを確かめます。

よろしくお願いします。

suke_suta

2024年9月25日 16時39分

高橋です、ありがとうございます

> 1.xxxxx-b.pyの先頭に、以下の3行を追加してみた上で、b.logの内容を添付してください。
>

> import sys
> import pprint
> pprint.pprint(sys.path)
> (元々の1行目)import serial
> 

この三行は crontab -e を起動させたときの xxxxx-b.py の前に追加という事で良いでしょうか?

> よろしくお願いします。

at_shota.shimoyama

2024年9月25日 16時47分

下山です。

いいえ、申し訳ありませんが、Pythonファイルであるxxxxx-b.py自体を編集してください。
おそらく今のxxxxx-b.pyの中身の1行目は「import serial」となっているはずですが、
その上に3行を追加してください。(「import serial」が4行目にくるということになります)

問題が解決したら追加した3行を削除していただいて全く問題ありません。
ひとまずこのような対処となりますがよろしくお願いします。

suke_suta

2024年9月25日 17時11分

高橋です、お手数かけして申し訳ありません

1が下のような結果になりました

PORT = "/dev/ttyUSB0"
BAUD_RATE = 115200
DATA_BITS =8
PARITY = 'N'
STOP_BITS = 1
TIMEOUT = 0.3
"upload-b.py" 88 lines, 255 characters written
root@armadillo:~# cat /root/b.log
  File "upload-b.py", line 1
    mport sys
            ^
SyntaxError: invalid syntax

python3 -m pip show pyserial は入力しても何も出てこず

pip show pyserial と入力すると

Name: pyserial
Version: 3.5
Summary: Python Serial Port Extension
Home-page: https://github.com/pyserial/pyserial
Author: Chris Liechti
Author-email: cliechti@gmx.net
License: BSD
Location: /usr/local/lib/python2.7/dist-packages
Requires: 
Required-by: 

と表示されました

よろしくお願いします。

at_shota.shimoyama

2024年9月25日 17時28分

下山です。

ログを提示していただきありがとうございます。

まず1についてですが、

mport sys

のように、先頭の「i」の文字がかけてしまっています。
おそらく正しく編集できていないのではないかと思われます。
正しくは

import sys

ですので、再度、3行を正しく追加できているか確認していただけないでしょうか?

2についてですが、
Location: /usr/local/lib/python2.7/dist-packagesとなっており、
python2.7とあるとおり、python3ではなくpythonのパッケージとしてインストールされてしまっているようです。
これについては申し訳ありません。これは私が先ほどpyserialのインストール方法として、

pip install pyserial

として提示してしまっていたからかと思われます。
Pythonの方ではなくPython3でインストールするための正しいコマンドは

python3 -m pip install pyserial

になりますので、こちらのコマンドでpyserialをインストールしていただけますでしょうか?

よろしくおねがいします。

suke_suta

2024年9月26日 8時17分

高橋です

['/root',
 '/usr/lib/python37.zip',
 '/usr/lib/python3.7',
 '/usr/lib/python3.7/lib-dynload',
 '/usr/local/lib/python3.7/dist-packages',
 '/usr/lib/python3/dist-packages']
Traceback (most recent call last):
  File "upload-b.py", line 10, in <module>
    import webDb as wd
  File "/root/webDb.py", line 1, in <module>
    import requests
ModuleNotFoundError: No module named 'requests'
 


>

root@armadillo:~# python3 -m pip show pyserial
Name: pyserial
Version: 3.5
Summary: Python Serial Port Extension
Home-page: https://github.com/pyserial/pyserial
Author: Chris Liechti
Author-email: cliechti@gmx.net
License: BSD
Location: /usr/local/lib/python3.7/dist-packages
Requires: 
Required-by: 

このようになりました、よろしくお願いします

at_shota.shimoyama

2024年9月26日 10時58分

下山です。

コマンド出力結果の添付ありがとうございます。
原因はPyhon3の方ではなくPythonの方にpyserialがインストールされていたためでした。
2のLocation: /usr/local/lib/python3.7/dist-packagesのとおり、現在はPython3の方にもpyserialがインストールされていますので、
こちらの原因は解消されております。

また、Python・Python3は、.pyファイルを1行目→2行目→3行目→…と上の行から順番に実行していくプログラミング言語です。
pyserialがインストールされていなかった際は、

File "upload-b.py", line 1, in <module>
 import serial

と1行目でエラーが発生していました。
pyserialがPython3にインストールされた現在は、添付いただいた1のとおり、

 File "upload-b.py", line 10, in <module>
    import webDb as wd

と10行目でエラーが発生しています。つまり、1行目から9行目までは正しく実行できたということになります。
ですので、ひとまずpyserialの問題については解決いたしましたので、今後は2の添付は必要ございません。ありがとうございました。

そして、現在発生しているエラーについてですが、

  File "upload-b.py", line 10, in <module>
    import webDb as wd
  File "/root/webDb.py", line 1, in <module>
    import requests
ModuleNotFoundError: No module named 'requests'

のように、upload-b.pyの1行目から9行目まではうまく実行されていますが、
10行目の

import webDb as wd

でエラーが発生しています。webDbはご自身で用意された/root/webDb.pyのことで、実際のエラーはこのファイル内で発生しています。
この行が実行されると、今度はwebDb.pyの1行目から実行されます。
そして、そのwebDb.pyの1行目の「import requests」で「requestsというモジュールが見つからない」というpyserialのときと同様のエラーが発生しています。

これを解決するためには、pyserialのときと同様、

python3 -m pip install requests

でPython3パッケージのrequestsをインストールしてください。

よろしくお願いします。

suke_suta

2024年9月26日 11時39分

高橋です

>

> python3 -m pip install requests
> 

> でPython3パッケージのrequestsをインストールしてください。

ありがとうございます、インストールして進めることができました

root@armadillo:~# cat /root/b.log
['/root',
 '/usr/lib/python37.zip',
 '/usr/lib/python3.7',
 '/usr/lib/python3.7/lib-dynload',
 '/usr/local/lib/python3.7/dist-packages',
 '/usr/lib/python3/dist-packages']
[error] Expecting value: line 1 column 1 (char 0)
Traceback (most recent call last):
  File "upload-b.py", line 36, in <module>
    for i in range(0,len(resultSensorSNs)):
TypeError: object of type 'NoneType' has no len()

upload-b.pyの36行目 for i in range(0,len(resultSensorSNs)): の部分でNoneTypeには len()の関数は使えないとでてるようですが
どこが原因でNoneTypeと判断されているのでしょうか?
自分では0が原因かと思ったのですが0のタイプは<'int'>のようです

> よろしくお願いします。

at_shota.shimoyama

2024年9月27日 10時51分

下山です。

TypeError: object of type 'NoneType' has no len()

このようなエラーが表示されている理由は、変数resultSensorSNsの値がNoneであるからかと思われます。
おそらくですが、resultSensorSNsという変数にはupload-b.pyの36行目よりも前の行で定義されていて、
そこではresultSensorSNsはリストやタプルなどのlen()が使用できるオブジェクトになることが期待されるようなプログラムなのだと思われます。

ですから上記のエラーを解決するためには、upload-b.pyの36行目をどうにかするのではなく、
それより前の行でのresultSensorSNsが定義されている行、または代入されている行において、
「なぜresultSensorSNsがリストやタプルなどではなくNoneになってしまっているのか」について調べることがデバッグの指針になるかと思います。

また開発の進め方についてですが、.pyファイルの内部でエラーが発生しているという今の現状では、
cronは使わずに、コマンドから直接

root@armadillo:~# python3 upload-b.py

のように実行する方法の方が、原因を切り分けやすくデバッグしやすいはずです。ご参考になれば幸いです。

よろしくお願いします。