jim-easterbrook / python-gphoto2

Python interface to libgphoto2
GNU Lesser General Public License v3.0
359 stars 59 forks source link

Memory Leak #102

Closed bitShakeMX closed 4 years ago

bitShakeMX commented 4 years ago

This page is for reporting problems with the Python interface to libgphoto2. If your question is about using libgphoto2 you should ask on the gphoto2 mailing list.

Your system What version of Python are you using? Pyrhon3

What version of libgphoto2 have you installed? 2.5.22

How have you installed (or attempted to install) python-gphoto2? Installed

I'm using python-gphoto2 to take photos every x time, the camera is configured to turn off every 30 seconds, I wake it up with a pulse to the shutter. My code:

def getPhoto(savePath, filename):
    #logging.basicConfig(
    #    format='%(levelname)s: %(name)s: %(message)s', level=logging.WARNING)
    #callback_obj = gp.check_result(gp.use_python_logging())
    camera = gp.Camera()
    camera.init()
    logging.info('Capturing image')
    file_path = camera.capture(gp.GP_CAPTURE_IMAGE)
    logging.info('Camera file path: %s/%s', file_path.folder, file_path.name )
    target = os.path.join(savePath, filename + '.jpg')
    logging.info("Copying image to %s", target)
    camera_file = camera.file_get(
        file_path.folder, file_path.name, gp.GP_FILE_TYPE_NORMAL)
    camera_file.save(target)
    camera.exit()
    return 0

def main():
    logging.basicConfig(level=logging.INFO, filename=logPath + projectName + datetime.datetime.now().strftime('_%Y%m%d.log'), format='[%(asctime)s] %(message)s') # include timestamp

    logger = logging.getLogger()

    # create console handler and set level to info
    handler = logging.StreamHandler()
    handler.setLevel(logging.INFO)
    formatter = logging.Formatter("%(levelname)s - %(message)s")
    handler.setFormatter(formatter)
    logger.addHandler(handler)

    #camera = gphoto(subprocess)

    logging.info("------------------------------------------------------------------------------------------------------------------------" )
    logging.info("Photos Interval: %s", intervalTime)

    shotCounter = 0

    while(True):

        logging.info("------------------------------------------------------------------------------------------------------------------------" )

        logging.info("Waking up Camera")
        GPIO.output(shutter, GPIO.HIGH) # Turn on
        sleep(shutterTime)
        GPIO.output(shutter, GPIO.LOW) # Turn off

        sleep(onCameraInterval)

        startMillis = int(round(time.time()))
        logging.info("Start milis: %s", startMillis)

        try:
            logging.info("Capturing.... Shot: %s", shotCounter)
            getPhoto(imagesPath, datetime.datetime.now().strftime('%Y-%m-%d-%H-%M-%S'))
            shotCounter = shotCounter + 1

        except Exception as e:
            logging.info("Error on capture: " + str(e))
            logging.info("Retrying...")

        endMillis = int(round(time.time()))
        logging.info("End milis: %s", endMillis)

        differenceMillis = endMillis - startMillis
        logging.info("Capture time: %s", differenceMillis)

        time.sleep(intervalTime - shutterTime - onCameraInterval - differenceMillis)

if __name__ == "__main__":
    sys.exit(main())

Issue: I mounted a systemd service to handle the execution of the code, but the RAM usage raises every cycle once takes the photo to the point code crashes.

jim-easterbrook commented 4 years ago

I can't see any obvious errors in that, although your use of logging is unconventional. One usually creates a logger (e.g. logger = logging.getLogger(__name__) at the top of the program and then calls its methods such as logger.info.)

What version of python-gphoto2 are you using and how did you install it?

Are you saying the leak only occurs when running under systemd?

jim-easterbrook commented 4 years ago

This short Python script can be used to check the versions of libgphoto2 and python-gphoto2.

import sys
import gphoto2 as gp

print('python:', sys.version)
print('libgphoto2:', gp.gp_library_version(gp.GP_VERSION_VERBOSE))
print('python-gphoto2:', gp.__version__)