-1

I'm new to Linux and am struggling a bit with a script

Hardware: Raspberry Pi Zero W

OS: Raspberry Pi OS Lite

the main script listen.py is waiting for a button push or udp command an then triggers the function take_image_ftp():

def take_image_ftp():
global scancounter
global isTakingImage
global denominator
global counter
global BUTTON

if  isTakingImage == False:
    isTakingImage = True
    
    GPIO.remove_event_detect(BUTTON)
    shutter = 1000000 / denominator #in microseconds 
    timea = datetime.utcnow()
    
    print("taking image...")
    subprocess.call(['raspistill -o /home/pi/startup/current.jpg --raw -md 3 -awb flash -q 100 -ex spotlight --timeout 2 --nopreview --shutter ' + str(shutter) +' --ISO 100'], shell=True)

    time.sleep(1)
    print("extracting dng...")
    subprocess.check_call(['python3.7 /home/pi/PyDNG/examples/utility.py current.jpg'], shell=True)
    
    timeb = datetime.utcnow()
    print("uploading image")
    from ftplib import FTP

    ftp = FTP(host="192.168.178.34",user='**', passwd='**')
    ftp.set_pasv(True)
    ftp.debug(0) 
    counter += 1
   # print("Shutter : " + str(shutter))
    #print ("logging in to ftp server ")
    try:
        ftp.login("Medusa", "Medusa")
    except ftplib.all_errors as e:
       # print('FTP error:', e)
        sys.exc_clear()


   # print("creating directory")
    try:
        ftp.cwd("images/")
    except ftplib.all_errors as e:
    #    print('FTP error:', e)
        sys.exc_clear()

    foldername = "img" + str(counter)
    if foldername not in ftp.nlst():
     #   print("folder does not exist. creating")
        try:
            ftp.mkd(foldername)

        except ftplib.all_errors as e:
         #   print('FTP error:', e)
            sys.exc_clear()
    try:
        ftp.cwd(foldername)
    except ftplib.all_errors as e:
        #print('FTP error:', e)
        sys.exc_clear()   

    if os.path.isfile('/home/pi/startup/current.dng'):
        file = open("/home/pi/startup/current.dng", "rb")
    else: 
        file = open("/home/pi/startup/listen.py","rb")

    ftp.storbinary("STOR " + str(get_ip_address('wlan0')) + ".dng", file)
    file.close()
    ftp.quit()
    timer = threading.Timer(5, resetCounter)
    timer.start()
    #print("\n")
    print("---------SCAN SENT--------")  
    #GPIO.add_event_detect(BUTTON, GPIO.RISING, callback=button_callback, bouncetime=200)
    print timeb - timea

It takes an image via raspistill(), then extracts the raw data from the captured image via PyDNG and then uploads the dng file via ftp.

When run via ssh as user pi it works like a charm, but when run via a autostart as root it craps (edit: runs out of memory) out at extracting the raw data. Which leads to the last image converted when run as user pi being uploaded.

helper script:

import socket
import struct
import fcntl
import subprocess
import sys
import ftplib
import time
import threading
import os

from time import sleep



print("updateing scripts")
try:
   ftp = ftplib.FTP("192.168.178.34", "**", "**")
   ftp.login("**", "**")
   lf = open("/home/pi/startup/listen.py", "wb")
   ftp.retrbinary("RETR " + "listen.py", lf.write, 8*1024)
   lf.close()
   lf = open("/home/pi/startup/focus.py", "wb")
   ftp.retrbinary("RETR " + "focus.py", lf.write, 8*1024)
   lf.close()
   ftp.quit()
except ftplib.all_errors as e:
print('FTP error:', e)

print("done")

print ("starting listen script")

cmd = ("python /home/pi/startup/listen.py")
subprocess.call(cmd, shell=True)

The helper script starts via /etc/rc.local sudo python /home/pi/startup/start.py &

If any of you could point me in the right direction, I'd very much appreciate it.

Frank
  • 19
  • 3
  • 1
    I have some trouble parsing the dialect "when it craps out". –  Feb 11 '21 at 09:51
  • sorry - it runs out of memory – Frank Feb 11 '21 at 09:57
  • `subprocess.call(['a complete command with options'], shell=True)` should basically be a syntax error, but weirdly isn't. It actually works, but you really mean either `subprocess.call('a complete command with options', shell=True)` without `[...]`, or (better) `subprocess.call(['a', 'complete', 'command', 'with', 'options'])` without `shell=True`. Better still. probably, use `subprocess.check_call()` or `subprocess.run(..., check=True)`. See also [Actual meaning of `shell=True`](https://stackoverflow.com/questions/3172470/actual-meaning-of-shell-true-in-subprocess) – tripleee Feb 11 '21 at 10:11
  • Having Python call itself as s subprocess is often dubious. In the startup script you should probably use `exec()` instead. In the main script, is there any reason not to `import` the modules you currently call as subprocesses, and run them directly within your main script? – tripleee Feb 11 '21 at 10:15
  • Why does `listen.py` upload itself!? – tripleee Feb 11 '21 at 10:16
  • @tripleee : Thanks! I will try this right away. "listen.py uploads it self" its a lazy way to tell me that the image was not captured /or converted. The hole thing has to run in a read only mode - so upon reboot there would be no previously taken image. – Frank Feb 11 '21 at 10:22
  • You could also arrange for the script to run as a non-root user at startup. – larsks Feb 11 '21 at 12:51
  • @larsks : sudo -u pi python3 ... already tried that. Not working though. I think I messed up with user rights along the way – Frank Feb 11 '21 at 14:20
  • No avail. every script is converted to python3. start.py now calls os.system('listen.py'). I also tried "import listen". Listen.py does now call the convert function via imported functions from PyDNG. I tried to log the output of listen.py by starting it via systemd which only indicates "raised valueerror" for pydng. I reinstalled pydng via sudo su - pip3 install -- system... nothing I am missing something – Frank Feb 11 '21 at 14:45

1 Answers1

1

Oh, boy... Here is the actual problem: When ssh-ing into the pi I change the working directory to the folder /startup. When running the script from systemd ... I didn't.

convert ('/home/pi/startup/current.jpg') instead of convert ('current.jpg')

goddamn hours man, goddamn hours.

Edit: the raspi did actually run out of memory when extracting the raw info from raspistill to dng using subprocess.call - so all the trouble was worth the effort!

thanks to everybody that replied!

Frank
  • 19
  • 3