3

概要:

9 時から 5 時の間にモーション センサーを制御する Python プログラムがあります。このプログラムはRaspberry Piで実行され、occidentals v2.1 Debian OSの SD メディアに保存されています。このプログラムは、勤務時間外にスリープし、翌日の午前 9 時に業務を再開するために、time.sleep メソッドに大きく依存しています。センサーがトリガーされると、ウェブカメラ経由で小さな写真が自動的に撮影されます。

問題:

最近までプログラムは正常に動作していましたが、ある朝、誰かがセンサーをトリガーし、take_picture() 関数が /dev/video0 の初期化に失敗しました。udev がデバイスを /dev/video* にマッピングしていなかったようで、ウェブカメラを再接続して「dmesg | tail」でステータスを確認したところ、次のエラーが表示されました。

[36725.201116] EXT4-fs error (device mmcblk0p2): udev

問題を調査し、ファイル システムの破損であるという結論に達した後、SD メディアでファイル システム チェックを実行しようとしました。そのプロセスで多くのエラーが解決されましたが、USB Web カメラを再マウントした後、同じ ext4-fs エラー メッセージが再発しました。

修正の試み #1

この時点で、OS を再インストールし、センサーの Python プログラムを再実行しました。2 日間、動作し、画像を送信し、眠りました。すべてが問題ないと思ったので、デバイスをシャットダウンして、センサーをより集中した場所に配置しました。

デバイスを起動し、 SSHpython接続からコマンドを実行しただけで、次のエラーが表示されました。

Traceback (most recent call last):
  File "/usr/lib/python2.7/site.py", line 562, in <module>
    main()
  File "/usr/lib/python2.7/site.py", line 544, in main
    known_paths = addusersitepackages(known_paths)
  File "/usr/lib/python2.7/site.py", line 271, in addusersitepackages
    user_site = getusersitepackages()
  File "/usr/lib/python2.7/site.py", line 246, in getusersitepackages
    user_base = getuserbase() # this will also set USER_BASE
  File "/usr/lib/python2.7/site.py", line 235, in getuserbase
    from sysconfig import get_config_var
ImportError: cannot import name get_config_var

プログラムが動作していてから再起動した後まで、設定は変更されていません。最悪の事態を想定して、「dmesg | tail」を再度チェックしたところ、さらに多くのファイルシステム エラーが発生しました。

[36725.201116] EXT4-fs error (device mmcblk0p2): ext4_ext_check_inode:403: inode #21266: comm python: bad header/extent: invalid extent entries - magic f30a, entries 1, max 4(4), depth 0(0)
[36725.239030] EXT4-fs error (device mmcblk0p2): ext4_ext_check_inode:403: inode #21427: comm python: bad header/extent: too large eh_max - magic f30a, entries 1, max 516(4), depth 0(0)

追加のファイルシステムのチェックと再起動の後、次を実行しpythonます。

[  819.427780] EXT4-fs error (device mmcblk0p2): ext4_ext_check_inode:403: inode #21266: comm python: bad header/extent: invalid extent entries - magic f30a, entries 1, max 4(4), depth 0(0)
[  819.470874] EXT4-fs error (device mmcblk0p2): ext4_ext_check_inode:403: inode #21427: comm python: bad header/extent: too large eh_max - magic f30a, entries 1, max 516(4), depth 0(0)
[  819.570893] EXT4-fs error (device mmcblk0p2): ext4_xattr_block_get:232: inode #21265: comm python: bad block 128

この時点で、これらのエラーの原因はプログラムのコアに関係しているのではないかと考えていますが、本質的には非常に単純で、画像を作成するときにディスクに書き込むだけです。以下は犯人コードです:

潜在的な問題のあるコード:

def take_picture():
    cam = pygame.camera.Camera("/dev/video0",(320,240))     #1280x960 max but slow
    pygame.init()
    cam.start()
    print "Capturing Image..."
    image_output = cam.get_image()
    pygame.image.save(image_output,'img_' +str(get_timestamp)+'.jpg')
    cam.stop()

# Activate PIR
def pir_init():
    while True:
        m = datetime.datetime.now().time().minute     #loop through for current time
        h = datetime.datetime.now().time().hour
        d = datetime.datetime.today().weekday()
        if d > 4:
            print("Sleeping...")
            print time_sleep
            time_sleep = (((7 - d) * 3600) * 24) - (h * 3600) + (9 * 3600)
            time.sleep(time_sleep)
        elif h < 9:
            print("Sleeping...")
            time_sleep = (9 - h) * 3600
            time.sleep(time_sleep)
        elif h > 16:
            print("Sleeping...")
            time_sleep = ((24 - h) + 9) * 3600
            time.sleep(time_sleep)
        elif io.input(pir_pin):
            print("PIR ALARM")
            pygame.camera.init()
            time.sleep(1.5)
            take_picture()
            send_gmail()
            time.sleep(10)      # Cooldown to prevent email spew
        else:
            print "Waiting..."
            time.sleep(0.5)     # Sleep and wait for movement
            print m
print "Wait"

上記で確認できる唯一の潜在的な問題は、画像の生成または長時間のスリープにある可能性があります。

これらの繰り返されるファイル システム エラーの原因は何ですか?

4

1 に答える 1

5

Raspberry Pi で SD カードが破損することはよくあることですが、このコードが直接これを引き起こすことはありません。

コードが問題を引き起こしていると私が考える唯一の理由は、SD カードへの書き込みが頻繁に試行される場合です。おそらく、SD カードの状態が悪いか、バッチが不良である可能性があります。

これらを単に電子メールとして送信する場合は、画像をハード ドライブにまったく保存しないこともできます。または、USB ハード ドライブまたはメモリ スティックを追加して、それを使用して写真を保存することもできます。

また、SD カードの負荷を軽減するために、各画像を直接書き込むのではなく、画像をキャッシュして一度に 2 枚ずつ書き込むこともできます。これは、たとえば 5 枚の写真をメモリに保存し、5 枚の写真を撮ったら、それらを書き出すのと同じくらい簡単です。

pictures = {}
pictures[get_timestamp] = image_output

次に、合計 5 つのエントリに達したら、それらをループし、キーを使用してファイル名を生成し、値には実際の画像が含まれます。次に、ハード ドライブに 5 つすべてを保存します。

512 MB のバージョンを使用している場合は、メモリに保存される画像の数を増やすことができますが、電源障害が発生した場合、メモリ内のすべてが失われることに注意してください.

于 2013-05-04T00:16:53.700 に答える