Overview:
I have a Python program that controls a motion sensor between the hours of 9-5. This program is running on a Raspberry Pi, stored on SD media with occidentals v2.1 Debian OS. The program relies heavily on the time.sleep method to sleep during off-hours and resume it's duties at 9 am, the next day. If the sensor triggers, it automatically takes a small picture via webcam.
Problem:
Until recently the program was working fine, until one morning when someone triggered the sensor and the take_picture() function failed to initialize /dev/video0. It seemed that udev wasn't mapping the device to /dev/video*, and when I re-plugged in the webcam and checked its status with "dmesg | tail", I received an error:
[36725.201116] EXT4-fs error (device mmcblk0p2): udev
After researching the problem and coming to the conclusion that it was filesystem corruption, I attempted to run a filesystem check on the SD media. Many errors were resolved in that process, but the same ext4-fs error messages reoccurred after re-mounting the USB webcam.
Fixing attempt #1
At this point I re-installed the OS and reran my sensor Python program; for two days it worked, sent images, and slept. I assumed that everything was OK, so I shutdown the device to place the sensor in more focused location.
After starting up the device and simply running the python
command from an SSH connection, I received this error:
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
No settings were changed between the time that the program was working and after I rebooted. I assumed the worst and checked "dmesg | tail" again and received more filesystem errors:
[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)
After an additional filesystem check and reboot, running 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
At this point I am thinking that the reason for these errors might have something to do with the core of my program, but in essence it is quite simple and only writes to disk upon creating pictures. Below is the culprit code:
Code with potential issue:
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"
The only potential issue I can see above might be with generating the picture or sleeping for an extended amount of time.
What might be causing these repeated filesystem errors?