jim-easterbrook / python-gphoto2

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

camera.wait_for_event works? #50

Closed dmitryelj closed 6 years ago

dmitryelj commented 6 years ago

Hi,

I'm testing the wait_for_event method now, the idea is to download the files.

        context = gp.Context()
        camera = gp.Camera()
        camera.init(context)

        while True:
                type, data = camera.wait_for_event(1000, context)
                print "gp_camera_wait_for_event:", type, data
                if type == gp.GP_EVENT_FILE_ADDED:
                    pass
                if type == gp.GP_EVENT_TIMEOUT:
                    pass

                time.sleep(0.5) # Solved: should be removed

The "type" is always 0, and the output looks like this: gp_camera_wait_for_event: 0 PTP Property d105 changed gp_camera_wait_for_event: 0 PTP Property d108 changed gp_camera_wait_for_event: 0 PTP Property d106 changed gp_camera_wait_for_event: 0 PTP Property d107 changed

Should it be different?

I'm checking the "sample-tether.c" code from a library (it works btw:), there are 2 additional parameters: CameraEventType evttype; CameraFilePath *path; retval = gp_camera_wait_for_event (camera, 1000, &evttype, &evtdata, context);

I tried to do the same like this (maybe wrong ctypes usage): intc = ctypes.c_int(0) char_data = ctypes.c_char_p(0) type, data = camera.wait_for_event(1000, ctypes.pointer(intc), ctypes.pointer(char_data), context)

But getting the error "TypeError: Camera_wait_for_event expected at most 2 arguments, got 4".

In the "camera.i" I see: MEMBER_FUNCTION_THREAD(_Camera, Camera, wait_for_event, (int timeout, CameraEventType *eventtype, void *eventdata, GPContext context), gp_camera_wait_for_event, ($self, timeout, eventtype, eventdata, context))

So, it should support 4 arguments? Or something was changed?

Thanks

jim-easterbrook commented 6 years ago

The Python version of gp_camera_wait_for_event returns event type and event data as in your line type, data = camera.wait_for_event(1000, context), hence it only takes the two arguments timeout and context. (I've attempted to explain this in the README: https://github.com/jim-easterbrook/python-gphoto2#c-interface)

Returning instantly with loads of PTP Property d105 changed style messages is normal. Once you've received all of those you'll start getting actual events.

PS Don't try and use ctypes stuff with python-gphoto2. It uses real Python types for everything.

dmitryelj commented 6 years ago

Thanks for answer. The question is, that "type" is always 0.

jim-easterbrook commented 6 years ago

If you want to try and decipher the camera.i file you also need to look at the %typemap stuff - it's where SWIG is really powerful. I use typemaps to tell SWIG that CameraEventType * eventtype, void ** eventdata in function arguments don't take them as inputs but apend them to the return value. https://github.com/jim-easterbrook/python-gphoto2/blob/master/src/gphoto2/camera.i#L253

jim-easterbrook commented 6 years ago

"type" is an enum - SWIG provides no means to translate back from the integer value to a meaningful name. 0 is GP_EVENT_UNKNOWN. http://www.gphoto.org/doc/api/gphoto2-camera_8h.html#a438ab2ac60ad5d5ced30e4201476800b

dmitryelj commented 6 years ago

Thanks a lot again. But why can it be always UNKNOWN? Wrong library path, version mismatch, etc?

jim-easterbrook commented 6 years ago

"PTP Property d105 changed" doesn't fit any of the other types and isn't handled. gp_camera_wait_for_event is (currently) only looking for timeout, file added, folder added, and capture complete events. Anything else is unknown and unhandled.

dmitryelj commented 6 years ago

Yes, this is all the log, I get, when pressing shutter:

gp_camera_wait_for_event: 0 PTP Property d105 changed
gp_camera_wait_for_event: 0 PTP Property d108 changed
gp_camera_wait_for_event: 0 PTP Property d106 changed
gp_camera_wait_for_event: 0 PTP Property d107 changed
gp_camera_wait_for_event: 0 PTP Property d109 changed
gp_camera_wait_for_event: 0 PTP Property d10a changed
gp_camera_wait_for_event: 0 PTP Property d10b changed
gp_camera_wait_for_event: 0 PTP Property d10c changed
gp_camera_wait_for_event: 0 PTP Property d10d changed
gp_camera_wait_for_event: 0 PTP Property d10e changed
gp_camera_wait_for_event: 0 PTP Property d10f changed
gp_camera_wait_for_event: 0 PTP Property d11b changed
gp_camera_wait_for_event: 0 PTP Property d114 changed
gp_camera_wait_for_event: 0 PTP Property d116 changed

This is a log, I get from sample-tether.c:

Unknown event: PTP Property d1c3 changed.
Unknown event: PTP Property d101 changed.
Unknown event: PTP Property d1d3 changed.
Unknown event: PTP Property d1c0 changed.
Unknown event: Button 2.
Unknown event: PTP Property d102 changed.
Unknown event: PTP Property d101 changed.
Unknown event: PTP Property d103 changed.
Unknown event: OLCInfo event mask=10f.
Unknown event: PTP Property d1c0 changed.
Unknown event: PTP Property d1d3 changed.
Unknown event: OLCInfo event 0x0800 content 1b4f604ab8ffe7ff.
Unknown event: OLCInfo event mask=900.
Unknown event: PTP Property d101 changed.
Unknown event: PTP Property d101 changed.
Unknown event: OLCInfo event mask=4.
Unknown event: PTP Property d1c3 changed.
Unknown event: Button 4.
Unknown event: OLCInfo event mask=1.
Unknown event: Camera Status 1.
Unknown event: PTP Property d11b changed.
Unknown event: OLCInfo event 0x0010 content 04029b2e.
Unknown event: OLCInfo event mask=10.
Unknown event: PTP Property d1d3 changed.
Unknown event: PTP Property d1c3 changed.
Unknown event: Button 2.
Unknown event: OLCInfo event 0x0800 content 0000000000000000.
Unknown event: OLCInfo event mask=801.
Unknown event: PTP Property d1c3 changed.
Unknown event: Button 3.
Unknown event: OLCInfo event mask=1.
Unknown event: PTP Property d1c0 changed.
Unknown event: OLCInfo event mask=100.
Unknown event: PTP Property d1d3 changed.
Unknown event: PTP Property d1c0 changed.
Unknown event: OLCInfo event mask=100.
File added on the camera: //capt0000.jpg
  Downloading capt0000.jpg...
  Deleting capt0000.jpg on camera...
Unknown event: PTP Property d103 changed.
Unknown event: OLCInfo event mask=8.
Capture Complete.
Unknown event: OLCInfo event 0x0010 content 04019b2e.
Unknown event: OLCInfo event mask=10.
Unknown event: PTP Property d101 changed.
Unknown event: PTP Property d101 changed.
Unknown event: OLCInfo event mask=4.
Unknown event: PTP Property d101 changed.
Unknown event: PTP Property d101 changed.
Unknown event: PTP Property d103 changed.
Unknown event: OLCInfo event mask=c.
Unknown event: PTP Property d1c3 changed.
Unknown event: PTP Property d101 changed.
Unknown event: Button 1.

Definitely more, but why?

jim-easterbrook commented 6 years ago

You appear to have only got as far as "gp_camera_wait_for_event: 0 PTP Property d116 changed". I'd expect more events to follow.

jim-easterbrook commented 6 years ago

I've added a simple event logging example in commit c0a3847.

dmitryelj commented 6 years ago

I checked again, it works. Because of time.sleep in cycle, I missed a lot of calls, stupid error.

PS: I also checked direct ctypes approach, also works ;) Maybe will be useful for somebody:

# ./ctypesgen.py -llibgphoto2.so -L/usr/local/lib /usr/include/gphoto2/gphoto2.h /usr/include/gphoto2/gphoto2-context.h /usr/include/gphoto2/gphoto2-camera.h -o gphoto.py

import gphoto as gp2

camera = gp2.POINTER(gp2.Camera)()

ret = gp2.gp_camera_new(gp2.byref(camera))

context = gp2.gp_context_new()

ret = gp2.gp_camera_init(camera, context)
print "gp_camera_init", ret

text = gp2.CameraText()
ret = gp2.gp_camera_get_summary(camera, gp2.pointer(text), context)
print "gp_camera_get_summary", ret, text.text

try:
        while True:
            evttype = gp2.c_int(0)
            evtdata = gp2.POINTER(None)()
            # evtdata = gp2.c_void_p()
            ret = gp2.gp_camera_wait_for_event(camera, 1000, gp2.pointer(evttype), gp2.byref(evtdata), context)
            print "gp_camera_wait_for_event", ret, evttype

            # time.sleep(0.5)

except KeyboardInterrupt:
        pass

ret = gp2.gp_camera_exit(camera, context)

ret = gp2.gp_camera_free(camera)
jim-easterbrook commented 6 years ago

Giving the ctypesgen module the same name as the Python-gphoto2 package is going to cause some confusion!

dmitryelj commented 6 years ago

Agree, changed.