parrot-developers / sequoia-ptpy Goto Github PK
View Code? Open in Web Editor NEWPython library used to communicate with PTP devices like Parrot Sequoia
License: BSD 3-Clause "New" or "Revised" License
Python library used to communicate with PTP devices like Parrot Sequoia
License: BSD 3-Clause "New" or "Revised" License
Hello. I will want use the PTPy library to comunicat the parrot sequoia camera by IP.
but i having a error in my code.
E 19 ptpy.ptp[MainThread:recv:801] 'module' object has no attribute 'TCP_QUICKACK'
Traceback (most recent call last):
File "/Users/starsky/StealingFired/nero-sequoia/trigger.py", line 11, in
main()
File "/Users/starsky/StealingFired/nero-sequoia/trigger.py", line 6, in main
NEROSequoia.trigger_camera_wifi()
File "/Users/starsky/StealingFired/nero-sequoia/NEROSequoia.py", line 23, in trigger_camera_wifi
c = PTPy(transport=IPTransport, device='197.168.47.1')
File "build/bdist.macosx-10.12-x86_64/egg/ptpy/init.py", line 114, in new
File "build/bdist.macosx-10.12-x86_64/egg/ptpy/ptp.py", line 953, in get_device_info
File "build/bdist.macosx-10.12-x86_64/egg/ptpy/ptp.py", line 802, in recv
AttributeError: 'module' object has no attribute 'TCP_QUICKACK'
Can you provide an example for file transfer please?
Testing versión 0.3 from PYPI. iPhone 6, iOS 11.1
jcea@jcea:~$ python
Python 2.7.14 (default, Sep 20 2017, 16:03:25)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ptpy import PTPy
>>> camera = PTPy()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/site-packages/ptpy/__init__.py", line 135, in __new__
instance._obtain_the_knowledge()
File "/usr/local/lib/python2.7/site-packages/ptpy/ptp.py", line 863, in _obtain_the_knowledge
self.__prop_desc[p] = self.get_device_prop_desc(p)
File "/usr/local/lib/python2.7/site-packages/ptpy/ptp.py", line 1059, in get_device_prop_desc
result = self._parse_if_data(response, self._DevicePropDesc)
File "/usr/local/lib/python2.7/site-packages/ptpy/ptp.py", line 824, in _parse_if_data
if hasattr(response, 'Data') else None)
File "/usr/local/lib/python2.7/site-packages/construct/core.py", line 158, in parse
return self.parse_stream(BytesIO(data), context, **kw)
File "/usr/local/lib/python2.7/site-packages/construct/core.py", line 171, in parse_stream
return self._parse(stream, context2, "(parsing)")
File "/usr/local/lib/python2.7/site-packages/construct/core.py", line 867, in _parse
subobj = sc._parse(stream, context, path)
File "/usr/local/lib/python2.7/site-packages/construct/core.py", line 2788, in _parse
raise e.__class__("%s\n %s" % (e, path))
construct.core.FieldError: could not read enough bytes, expected 128, found 33
(parsing) -> FactoryDefaultValue
This project would benefit from proper py module versioning and git tags, right now developers have to use whatever is on HEAD or fork and use a branch.
Can we please get better package versioning?
I want to use ptpy to communicate with my Sequoia. When I plug the sequoia into my Mac via USB and run the example, python ./trigger.py
, I get a ptpy.ptp.PTPError
:
E 439 ptpy.transports.usb[MainThread:__available_cameras:119] No USB PTP device found.
E 440 ptpy.transports.usb[MainThread:__available_cameras:119] No USB PTP device found.
Traceback (most recent call last):
File "./trigger.py", line 4, in <module>
camera = ptpy.PTPy()
File "/Users/adelinehillier/anaconda3/lib/python3.6/site-packages/ptpy/__init__.py", line 133, in __new__
instance = PTPy(device=device)
File "/Users/adelinehillier/anaconda3/lib/python3.6/site-packages/ptpy/ptp.py", line 712, in __init__
super(PTP, self).__init__(*args, **kwargs)
File "/Users/adelinehillier/anaconda3/lib/python3.6/site-packages/ptpy/transports/usb.py", line 92, in __init__
self.__acquire_camera(devs)
File "/Users/adelinehillier/anaconda3/lib/python3.6/site-packages/ptpy/transports/usb.py", line 125, in __acquire_camera
for _ in self.__available_cameras(devs):
File "/Users/adelinehillier/anaconda3/lib/python3.6/site-packages/ptpy/transports/usb.py", line 120, in __available_cameras
raise PTPError(message)
ptpy.ptp.PTPError: No USB PTP device found.
When I use a Raspberry Pi instead, I get the same error. In both cases, the sequoia is not recognized as a USB device under lsusb. Ideas?
Hello,
I realize that this is more of a "feature request" than an issue: it'd be great if we had some more advanced examples that showed things like
Thanks for writing and sharing this library, by the way.
Rick
I am trying to turn wifi on sequoia ON and OFF with following code:
#!/usr/bin/env python
import ptpy
camera = ptpy.PTPy()
with camera.session():
status = camera.set_device_prop_value('WifiStatus', 'ON')
print(status);
Response is:
Container:
TransactionID = 1
SessionID = 1
ResponseCode = InvalidDevicePropValue
Parameter = ListContainer:
I suspect problem is in unicode something. If get 'WifiStatus' it returns [u'ON',.......
When I run trigger.py, sequoia takes pictures, so i think my environment is set up correctly.
I have a Sensefly SODA camera which I am trying to trigger on a JetsonTX2 continuously for a set amount of seconds. Once every couple of image captures, the usb connection drops out and I get an "Operation timed out" message. Any idea how I can resolve this? I thought it might be a usb stability issue but swapping out the usb cable does not work.
The script can be found here:
#!/usr/bin/python
import ptpy
from ptpy.transports.usb import find_usb_cameras
from threading import Thread, Event
import sys
import logging
from rainbow_logging_handler import RainbowLoggingHandler
from time import sleep, time
import os
import argparse
import sys
from datetime import datetime
# Run Command: python3 camera.py --time 60
# parse the command line
parser = argparse.ArgumentParser(description="Script to trigger camera", formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument("--time", type=int, default=30, help="number of minutes to take images")
try:
opt, argv = parser.parse_known_args()
except:
print("")
parser.print_help()
sys.exit(0)
# Set up log
log = logging.getLogger('Live')
formatter = logging.Formatter(
'%(levelname).1s '
'%(relativeCreated)d '
'%(name)s'
'[%(threadName)s] '
'%(message)s'
)
handler = RainbowLoggingHandler(
sys.stderr,
)
level = 'INFO'
log.setLevel(level)
handler.setFormatter(formatter)
log.addHandler(handler)
# get datetime
now = datetime.now()
date_time = now.strftime("%d%m%y_%H%M%S")
# Set up directories
cur_dir = os.getcwd()
save_dir = os.path.join(cur_dir, 'SODA_images_{}'.format(date_time))
if not os.path.exists(save_dir):
os.makedirs(save_dir)
try:
camera = ptpy.PTPy()
info = camera.get_device_info()
caminfo = (info.Manufacturer, info.Model, info.SerialNumber)
if (
'InitiateCapture' not in info.OperationsSupported or
'GetObject' not in info.OperationsSupported
):
raise Exception(
'{} {} {} does not support capture or download...'
.format(*caminfo)
)
log.info(
'Found {} {} {}'
.format(*caminfo)
)
timeout = opt.time * 60
timeout_start = time()
with camera.session():
info = camera.get_device_info()
while time() < timeout_start + timeout:
capture = camera.initiate_capture()
event = camera.event()
print(event)
if capture.ResponseCode == 'OK':
log.info('{}: successfully initiated capture'.format(info.SerialNumber))
except Exception as e:
log.error(e)
And the diagnostic log with export PYUSB_DEBUG=debug and export PTPY_DEBUG=1 can be found here.
diagnostic_log_camera2.txt
Hello,
(this issue is very similar to #20 but I decided to make a new one because it was quite old.)
I cannot connect to my Nikon d7200 via IP using the library. Here's my code:
from ptpy import PTPy
from ptpy.transports.ip import IPTransport
c = PTPy(transport=IPTransport, device='192.168.1.1')
The ip address is correct, since another (but less sophisticated) library is able to connect with the same address. The error I get is:
E 65729 ptpy.transports.ip[MainThread:__implicit_session:115] <lambda>() missing 1 required positional argument: 'lst'
E 65729 ptpy.ptp[MainThread:recv:801] Failed to open PTP/IP implicit session
Traceback (most recent call last):
File "/home/kaappo/.local/lib/python3.7/site-packages/ptpy/transports/ip.py", line 111, in __implicit_session
self.__open_implicit_session()
File "/home/kaappo/.local/lib/python3.7/site-packages/ptpy/transports/ip.py", line 136, in __open_implicit_session
self.__setup_connection(self.__device)
File "/home/kaappo/.local/lib/python3.7/site-packages/ptpy/transports/ip.py", line 208, in __setup_connection
Minor=000,
File "/home/kaappo/.local/lib/python3.7/site-packages/construct/core.py", line 203, in build
self.build_stream(obj, stream, context, **kw)
File "/home/kaappo/.local/lib/python3.7/site-packages/construct/core.py", line 215, in build_stream
self._build(obj, stream, context, "building")
File "/home/kaappo/.local/lib/python3.7/site-packages/construct/core.py", line 299, in _build
return self.subcon._build(obj, stream, context, path)
File "/home/kaappo/.local/lib/python3.7/site-packages/construct/core.py", line 874, in _build
buildret = sc._build(subobj, stream, context, path)
File "/home/kaappo/.local/lib/python3.7/site-packages/construct/core.py", line 2704, in _build
return self.subcon._build(obj, stream, context, path)
File "/home/kaappo/.local/lib/python3.7/site-packages/construct/core.py", line 315, in _build
return self.subcon._build(self._encode(obj, context), stream, context, path)
File "/home/kaappo/.local/lib/python3.7/site-packages/construct/core.py", line 1133, in _build
if self.predicate(subobj, context):
TypeError: <lambda>() missing 1 required positional argument: 'lst'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/kaappo/.local/lib/python3.7/site-packages/ptpy/__init__.py", line 114, in __new__
device_info = plain_camera.get_device_info()
File "/home/kaappo/.local/lib/python3.7/site-packages/ptpy/ptp.py", line 953, in get_device_info
response = self.recv(ptp)
File "/home/kaappo/.local/lib/python3.7/site-packages/ptpy/ptp.py", line 802, in recv
raise e
File "/home/kaappo/.local/lib/python3.7/site-packages/ptpy/ptp.py", line 799, in recv
return super(PTP, self).recv(ptp_container)
File "/home/kaappo/.local/lib/python3.7/site-packages/ptpy/transports/ip.py", line 600, in recv
with self.__implicit_session():
File "/usr/lib/python3.7/contextlib.py", line 112, in __enter__
return next(self.gen)
File "/home/kaappo/.local/lib/python3.7/site-packages/ptpy/transports/ip.py", line 116, in __implicit_session
raise PTPError('Failed to open PTP/IP implicit session')
ptpy.ptp.PTPError: Failed to open PTP/IP implicit session
Construct 2.8 uses deprecated imports from collections which breaks on python 3.10.
Updating would mostly mean replacing Range
and Embed
.
When I did pip install ptpy
it wouldn't import:
>>> import ptpy
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ptpy/__init__.py", line 3, in <module>
from .extensions.canon import PTPDevice as canon
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ptpy/extensions/canon.py", line 6, in <module>
from .. import ptp
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ptpy/ptp.py", line 13, in <module>
from construct import (
ImportError: cannot import name BitField
This appears to be due to a change in the 2.5-2.8 transition of construct:
https://github.com/construct/construct/blob/a5e76e247f23065596e321fd2dded8fe49e1b103/docs/transition.rst
Hi,
when i tried the print_device_info example with my Sony a58 over usb i got the following error:
I don't know if its a bug with your library or pyusb/libusb in combination with my OS (Kubuntu 18.04)
export PYUSB_DEBUG=debug
export PTPY_DEBUG=1
python print_device_info.py > print_device_info.log 2>&1
print_device_info.log:
D 22 ptpy[MainThread:__new__:99] New PTPy
D 22 ptpy[MainThread:__new__:101] Determining available transports
D 22 ptpy.ptp[MainThread:__init__:705] Init PTP
D 22 ptpy.transports.usb[MainThread:__init__:72] Init USB
D 23 ptpy.ptp[MainThread:_set_endian:629] Set PTP endianness
D 23 ptpy.transports.usb[MainThread:__init__:77] No device provided, probing all USB devices.
2018-04-30 15:21:48,310 DEBUG:usb.backend.libusb1:_LibUSB.__init__(<CDLL 'libusb-1.0.so.0', handle 557aabf58050 at 0x7f9df861b0f0>)
2018-04-30 15:21:48,313 INFO:usb.core:find(): using backend "usb.backend.libusb1"
2018-04-30 15:21:48,314 DEBUG:usb.backend.libusb1:_LibUSB.enumerate_devices()
2018-04-30 15:21:48,314 DEBUG:usb.backend.libusb1:_LibUSB.get_device_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>)
2018-04-30 15:21:48,314 DEBUG:usb.backend.libusb1:_LibUSB.get_configuration_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0)
2018-04-30 15:21:48,315 DEBUG:usb.backend.libusb1:_LibUSB.get_interface_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0, 0, 0)
2018-04-30 15:21:48,315 DEBUG:usb.backend.libusb1:_LibUSB.get_configuration_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0)
2018-04-30 15:21:48,315 DEBUG:usb.backend.libusb1:_LibUSB.get_configuration_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0)
2018-04-30 15:21:48,315 DEBUG:usb.backend.libusb1:_LibUSB.get_interface_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0, 0, 0)
2018-04-30 15:21:48,315 DEBUG:usb.backend.libusb1:_LibUSB.get_configuration_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0)
2018-04-30 15:21:48,315 DEBUG:usb.backend.libusb1:_LibUSB.get_endpoint_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0, 0, 0, 0)
2018-04-30 15:21:48,315 DEBUG:usb.backend.libusb1:_LibUSB.get_interface_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0, 0, 0)
2018-04-30 15:21:48,315 DEBUG:usb.backend.libusb1:_LibUSB.get_configuration_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0)
2018-04-30 15:21:48,315 DEBUG:usb.backend.libusb1:_LibUSB.get_endpoint_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 1, 0, 0, 0)
2018-04-30 15:21:48,316 DEBUG:usb.backend.libusb1:_LibUSB.get_interface_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0, 0, 0)
2018-04-30 15:21:48,316 DEBUG:usb.backend.libusb1:_LibUSB.get_configuration_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0)
2018-04-30 15:21:48,316 DEBUG:usb.backend.libusb1:_LibUSB.get_endpoint_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 2, 0, 0, 0)
2018-04-30 15:21:48,316 DEBUG:usb.backend.libusb1:_LibUSB.get_interface_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0, 0, 0)
2018-04-30 15:21:48,316 DEBUG:usb.backend.libusb1:_LibUSB.get_configuration_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0)
D 50 ptpy.transports.usb[MainThread:__setup_device:205] Found <ENDPOINT 0x81: Bulk IN>
D 50 ptpy.transports.usb[MainThread:__setup_device:206] Found <ENDPOINT 0x2: Bulk OUT>
D 50 ptpy.transports.usb[MainThread:__setup_device:207] Found <ENDPOINT 0x83: Interrupt IN>
2018-04-30 15:21:48,316 DEBUG:usb.backend.libusb1:_LibUSB.open_device(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>)
2018-04-30 15:21:48,451 DEBUG:usb.backend.libusb1:_LibUSB.ctrl_transfer(<usb.backend.libusb1._DeviceHandle object at 0x7f9df6693da0>, 128, 6, 768, 0, array('B', [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1000)
2018-04-30 15:21:48,453 DEBUG:usb.backend.libusb1:_LibUSB.ctrl_transfer(<usb.backend.libusb1._DeviceHandle object at 0x7f9df6693da0>, 128, 6, 769, 1033, array('B', [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1000)
2018-04-30 15:21:48,456 DEBUG:usb.backend.libusb1:_LibUSB.ctrl_transfer(<usb.backend.libusb1._DeviceHandle object at 0x7f9df6693da0>, 128, 6, 770, 1033, array('B', [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1000)
2018-04-30 15:21:48,457 DEBUG:usb.backend.libusb1:_LibUSB.ctrl_transfer(<usb.backend.libusb1._DeviceHandle object at 0x7f9df6693da0>, 128, 6, 771, 1033, array('B', [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1000)
2018-04-30 15:21:48,460 DEBUG:usb.backend.libusb1:_LibUSB.get_configuration_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0)
2018-04-30 15:21:48,460 DEBUG:usb.backend.libusb1:_LibUSB.get_interface_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0, 0, 0)
2018-04-30 15:21:48,460 DEBUG:usb.backend.libusb1:_LibUSB.get_configuration_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0)
2018-04-30 15:21:48,460 DEBUG:usb.backend.libusb1:_LibUSB.get_endpoint_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0, 0, 0, 0)
2018-04-30 15:21:48,460 DEBUG:usb.backend.libusb1:_LibUSB.get_interface_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0, 0, 0)
2018-04-30 15:21:48,461 DEBUG:usb.backend.libusb1:_LibUSB.get_configuration_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0)
2018-04-30 15:21:48,461 DEBUG:usb.backend.libusb1:_LibUSB.get_endpoint_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 1, 0, 0, 0)
2018-04-30 15:21:48,461 DEBUG:usb.backend.libusb1:_LibUSB.get_interface_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0, 0, 0)
2018-04-30 15:21:48,461 DEBUG:usb.backend.libusb1:_LibUSB.get_configuration_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0)
2018-04-30 15:21:48,461 DEBUG:usb.backend.libusb1:_LibUSB.get_endpoint_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 2, 0, 0, 0)
2018-04-30 15:21:48,461 DEBUG:usb.backend.libusb1:_LibUSB.get_interface_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0, 0, 0)
2018-04-30 15:21:48,461 DEBUG:usb.backend.libusb1:_LibUSB.get_configuration_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0)
2018-04-30 15:21:48,462 DEBUG:usb.backend.libusb1:_LibUSB.get_interface_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0, 1, 0)
2018-04-30 15:21:48,462 DEBUG:usb.backend.libusb1:_LibUSB.get_configuration_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0)
D 196 ptpy.transports.usb[MainThread:__available_cameras:115] Found USB PTP device DEVICE ID 054c:0737 on Bus 002 Address 010 =================
bLength : 0x12 (18 bytes)
bDescriptorType : 0x1 Device
bcdUSB : 0x200 USB 2.0
bDeviceClass : 0x0 Specified at interface
bDeviceSubClass : 0x0
bDeviceProtocol : 0x0
bMaxPacketSize0 : 0x40 (64 bytes)
idVendor : 0x054c
idProduct : 0x0737
bcdDevice : 0x200 Device 2.0
iManufacturer : 0x1 Sony
iProduct : 0x2 SLT-A58
iSerialNumber : 0x3 597C70442A3D
bNumConfigurations : 0x1
CONFIGURATION 1: 2 mA ====================================
bLength : 0x9 (9 bytes)
bDescriptorType : 0x2 Configuration
wTotalLength : 0x27 (39 bytes)
bNumInterfaces : 0x1
bConfigurationValue : 0x1
iConfiguration : 0x0
bmAttributes : 0xc0 Self Powered
bMaxPower : 0x1 (2 mA)
INTERFACE 0: Image =====================================
bLength : 0x9 (9 bytes)
bDescriptorType : 0x4 Interface
bInterfaceNumber : 0x0
bAlternateSetting : 0x0
bNumEndpoints : 0x3
bInterfaceClass : 0x6 Image
bInterfaceSubClass : 0x1
bInterfaceProtocol : 0x1
iInterface : 0x0
ENDPOINT 0x81: Bulk IN ===============================
bLength : 0x7 (7 bytes)
bDescriptorType : 0x5 Endpoint
bEndpointAddress : 0x81 IN
bmAttributes : 0x2 Bulk
wMaxPacketSize : 0x200 (512 bytes)
bInterval : 0x0
ENDPOINT 0x2: Bulk OUT ===============================
bLength : 0x7 (7 bytes)
bDescriptorType : 0x5 Endpoint
bEndpointAddress : 0x2 OUT
bmAttributes : 0x2 Bulk
wMaxPacketSize : 0x200 (512 bytes)
bInterval : 0x0
ENDPOINT 0x83: Interrupt IN ==========================
bLength : 0x7 (7 bytes)
bDescriptorType : 0x5 Endpoint
bEndpointAddress : 0x83 IN
bmAttributes : 0x3 Interrupt
wMaxPacketSize : 0x20 (32 bytes)
bInterval : 0x7
2018-04-30 15:21:48,462 DEBUG:usb.backend.libusb1:_LibUSB.is_kernel_driver_active(<usb.backend.libusb1._DeviceHandle object at 0x7f9df6693da0>, 0)
D 196 ptpy.transports.usb[MainThread:__acquire_camera:143] Claiming <DEVICE ID 054c:0737 on Bus 002 Address 010>
2018-04-30 15:21:48,463 DEBUG:usb.backend.libusb1:_LibUSB.claim_interface(<usb.backend.libusb1._DeviceHandle object at 0x7f9df6693da0>, 0)
2018-04-30 15:21:48,463 DEBUG:usb.backend.libusb1:_LibUSB.release_interface(<usb.backend.libusb1._DeviceHandle object at 0x7f9df6693da0>, 0)
2018-04-30 15:21:48,463 DEBUG:usb.backend.libusb1:_LibUSB.reset_device(<usb.backend.libusb1._DeviceHandle object at 0x7f9df6693da0>)
2018-04-30 15:21:48,661 DEBUG:usb.backend.libusb1:_LibUSB.close_device(<usb.backend.libusb1._DeviceHandle object at 0x7f9df6693da0>)
2018-04-30 15:21:48,662 DEBUG:usb.backend.libusb1:_LibUSB.open_device(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>)
D 396 ptpy.transports.usb[MainThread:recv:480] RECV GetDeviceInfo
2018-04-30 15:21:48,663 DEBUG:usb.backend.libusb1:_LibUSB.get_configuration(<usb.backend.libusb1._DeviceHandle object at 0x7f9df57f32b0>)
2018-04-30 15:21:48,663 DEBUG:usb.backend.libusb1:_LibUSB.get_configuration_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0)
2018-04-30 15:21:48,663 DEBUG:usb.backend.libusb1:_LibUSB.get_interface_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0, 0, 0)
2018-04-30 15:21:48,663 DEBUG:usb.backend.libusb1:_LibUSB.get_configuration_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0)
2018-04-30 15:21:48,664 DEBUG:usb.backend.libusb1:_LibUSB.get_endpoint_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0, 0, 0, 0)
2018-04-30 15:21:48,664 DEBUG:usb.backend.libusb1:_LibUSB.get_interface_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0, 0, 0)
2018-04-30 15:21:48,664 DEBUG:usb.backend.libusb1:_LibUSB.get_configuration_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0)
2018-04-30 15:21:48,664 DEBUG:usb.backend.libusb1:_LibUSB.get_endpoint_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 1, 0, 0, 0)
2018-04-30 15:21:48,664 DEBUG:usb.backend.libusb1:_LibUSB.get_interface_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0, 0, 0)
2018-04-30 15:21:48,664 DEBUG:usb.backend.libusb1:_LibUSB.get_configuration_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0)
2018-04-30 15:21:48,664 DEBUG:usb.backend.libusb1:_LibUSB.get_endpoint_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 2, 0, 0, 0)
2018-04-30 15:21:48,664 DEBUG:usb.backend.libusb1:_LibUSB.get_interface_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0, 0, 0)
2018-04-30 15:21:48,664 DEBUG:usb.backend.libusb1:_LibUSB.get_configuration_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0)
2018-04-30 15:21:48,665 DEBUG:usb.backend.libusb1:_LibUSB.claim_interface(<usb.backend.libusb1._DeviceHandle object at 0x7f9df57f32b0>, 0)
2018-04-30 15:21:48,665 DEBUG:usb.backend.libusb1:_LibUSB.intr_read(<usb.backend.libusb1._DeviceHandle object at 0x7f9df57f32b0>, 131, 0, array('B', [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1000)
2018-04-30 15:21:48,665 DEBUG:usb.backend.libusb1:_LibUSB.get_configuration_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0)
2018-04-30 15:21:48,665 DEBUG:usb.backend.libusb1:_LibUSB.get_interface_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0, 0, 0)
2018-04-30 15:21:48,665 DEBUG:usb.backend.libusb1:_LibUSB.get_configuration_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0)
2018-04-30 15:21:48,666 DEBUG:usb.backend.libusb1:_LibUSB.get_endpoint_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0, 0, 0, 0)
2018-04-30 15:21:48,666 DEBUG:usb.backend.libusb1:_LibUSB.get_interface_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0, 0, 0)
2018-04-30 15:21:48,666 DEBUG:usb.backend.libusb1:_LibUSB.get_configuration_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0)
2018-04-30 15:21:48,666 DEBUG:usb.backend.libusb1:_LibUSB.get_endpoint_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 1, 0, 0, 0)
2018-04-30 15:21:48,667 DEBUG:usb.backend.libusb1:_LibUSB.get_interface_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0, 0, 0)
2018-04-30 15:21:48,667 DEBUG:usb.backend.libusb1:_LibUSB.get_configuration_descriptor(<usb.backend.libusb1._Device object at 0x7f9dfb5a1320>, 0)
2018-04-30 15:21:48,667 DEBUG:usb.backend.libusb1:_LibUSB.bulk_write(<usb.backend.libusb1._DeviceHandle object at 0x7f9df57f32b0>, 2, 0, array('B', [12, 0, 0, 0, 1, 0, 1, 16, 0, 0, 0, 0]), 1000)
2018-04-30 15:21:49,671 DEBUG:usb.backend.libusb1:_LibUSB.intr_read(<usb.backend.libusb1._DeviceHandle object at 0x7f9df57f32b0>, 131, 0, array('B', [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1000)
2018-04-30 15:21:49,672 DEBUG:usb.backend.libusb1:_LibUSB.bulk_write(<usb.backend.libusb1._DeviceHandle object at 0x7f9df57f32b0>, 2, 0, array('B', [12, 0, 0, 0, 1, 0, 1, 16, 0, 0, 0, 0]), 1000)
2018-04-30 15:21:50,679 DEBUG:usb.backend.libusb1:_LibUSB.intr_read(<usb.backend.libusb1._DeviceHandle object at 0x7f9df57f32b0>, 131, 0, array('B', [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 1000)
E 2413 ptpy.ptp[MainThread:recv:801] [Errno 110] Operation timed out
Traceback (most recent call last):
File "/home/waldi/.pyenv/versions/photobox/lib/python3.6/site-packages/ptpy/transports/usb.py", line 402, in __send
ep.write(transaction)
File "/home/waldi/.pyenv/versions/photobox/lib/python3.6/site-packages/usb/core.py", line 387, in write
return self.device.write(self, data, timeout)
File "/home/waldi/.pyenv/versions/photobox/lib/python3.6/site-packages/usb/core.py", line 948, in write
self.__get_timeout(timeout)
File "/home/waldi/.pyenv/versions/photobox/lib/python3.6/site-packages/usb/_debug.py", line 60, in do_trace
return f(*args, **named_args)
File "/home/waldi/.pyenv/versions/photobox/lib/python3.6/site-packages/usb/backend/libusb1.py", line 824, in bulk_write
timeout)
File "/home/waldi/.pyenv/versions/photobox/lib/python3.6/site-packages/usb/backend/libusb1.py", line 920, in __write
_check(retval)
File "/home/waldi/.pyenv/versions/photobox/lib/python3.6/site-packages/usb/backend/libusb1.py", line 595, in _check
raise USBError(_strerror(ret), ret, _libusb_errno[ret])
usb.core.USBError: [Errno 110] Operation timed out
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "print_device_info.py", line 4, in <module>
camera = ptpy.PTPy()
File "/home/waldi/.pyenv/versions/photobox/lib/python3.6/site-packages/ptpy/__init__.py", line 114, in __new__
device_info = plain_camera.get_device_info()
File "/home/waldi/.pyenv/versions/photobox/lib/python3.6/site-packages/ptpy/ptp.py", line 953, in get_device_info
response = self.recv(ptp)
File "/home/waldi/.pyenv/versions/photobox/lib/python3.6/site-packages/ptpy/ptp.py", line 802, in recv
raise e
File "/home/waldi/.pyenv/versions/photobox/lib/python3.6/site-packages/ptpy/ptp.py", line 799, in recv
return super(PTP, self).recv(ptp_container)
File "/home/waldi/.pyenv/versions/photobox/lib/python3.6/site-packages/ptpy/transports/usb.py", line 483, in recv
self.__send_request(ptp_container)
File "/home/waldi/.pyenv/versions/photobox/lib/python3.6/site-packages/ptpy/transports/usb.py", line 430, in __send_request
self.__send(ptp)
File "/home/waldi/.pyenv/versions/photobox/lib/python3.6/site-packages/ptpy/transports/usb.py", line 411, in __send
ep.write(transaction)
File "/home/waldi/.pyenv/versions/photobox/lib/python3.6/site-packages/usb/core.py", line 387, in write
return self.device.write(self, data, timeout)
File "/home/waldi/.pyenv/versions/photobox/lib/python3.6/site-packages/usb/core.py", line 948, in write
self.__get_timeout(timeout)
File "/home/waldi/.pyenv/versions/photobox/lib/python3.6/site-packages/usb/_debug.py", line 60, in do_trace
return f(*args, **named_args)
File "/home/waldi/.pyenv/versions/photobox/lib/python3.6/site-packages/usb/backend/libusb1.py", line 824, in bulk_write
timeout)
File "/home/waldi/.pyenv/versions/photobox/lib/python3.6/site-packages/usb/backend/libusb1.py", line 920, in __write
_check(retval)
File "/home/waldi/.pyenv/versions/photobox/lib/python3.6/site-packages/usb/backend/libusb1.py", line 595, in _check
raise USBError(_strerror(ret), ret, _libusb_errno[ret])
usb.core.USBError: [Errno 110] Operation timed out
D 3417 ptpy.transports.usb[MainThread:_shutdown:159] Shutdown request
D 3417 ptpy.transports.usb[MainThread:_shutdown:169] Release <DEVICE ID 054c:0737 on Bus 002 Address 010>
2018-04-30 15:21:51,684 DEBUG:usb.backend.libusb1:_LibUSB.release_interface(<usb.backend.libusb1._DeviceHandle object at 0x7f9df57f32b0>, 0)
2018-04-30 15:21:51,685 DEBUG:usb.backend.libusb1:_LibUSB.close_device(<usb.backend.libusb1._DeviceHandle object at 0x7f9df57f32b0>)
2018-04-30 15:21:51,687 DEBUG:usb.backend.libusb1:_LibUSB._finalize_object()
There is no "clean" way to stop the usb connection without a shutdown!
It would be great if we were able to release the usb interface when deleting the PTPy class.
From what i have seen there is no real proper way to release the usb interface.
Thanks for this cool piece of software. I like to contribute.
Using commit 3bc34c6
from ptpy import PTPy
camera = PTPy()
print camera.get_device_info()
print camera.open_session()
print camera.initiate_capture()
yields:
python test_ptp.py
Container:
StandardVersion = 100
VendorExtensionID = Microsoft
VendorExtensionVersion = 100
VendorExtensionDesc =
FunctionalMode = 0
OperationsSupported = ['GetDeviceInfo', 'OpenSession', 'CloseSession', 'GetDevicePropDesc', 'GetDevicePropValue', 'SetDevicePropValue', 37333, 'GetObjectPropsSupported', 'GetObjectPropDesc', 'GetObjectPropValue', 'SetObjectPropValue', 'GetObjPropList', 'GetNumObjects', 'GetStorageIDs', 'GetSecureTimeChallenge', 'GetStorageInfo', 'GetSecureTimeResponse', 'GetObjectHandles', 'GetObjectInfo', 'SetLicenseResponse', 'GetObject', 'GetSyncList', 'GetThumb', 'GetPartialObject', 'SetMeterResponse', 'SendObjectInfo', 'SendObject', 'DeleteObject', 'SendMeterChallengeQuery', 'FormatStore', 'GetMeterChallenge', 37136, 37159, 'SendWMDRMPDRequest', 'CleanDataStore', 'GetLicenseState', 37132, 37134, 37135, 37143, 37152, 37360, 37144, 37153, 37361, 37149, 'SendWMDRMPDCommand', 37147, 37148, 37150, 37146, 37185, 37186, 37187, 37188, 37189, 37184, 37203, 37204, 37216, 37205, 37207, 37208, 37209, 37210, 37151, 37374, 37375, 37160, 37161, 37165, 37166, 37167, 37164, 37168, 37169, 37170, 37171, 37172, 37163, 37173, 37174, 37175, 37176, 37177, 37178, 37179, 37180, 37181, 37183, 37338, 37339, 37340, 37341, 37342, 37336, 37337, 37335, 37182, 37139, 37140, 37141, 37142, 37312, 37313, 37314, 37315, 37316, 37317, 37318, 37319, 37320, 37321, 37322, 37323, 37324, 37326, 37327, 37328, 37329, 37330, 37345, 37346, 37347, 37348, 37349, 37350, 37351, 37352, 37353, 37354, 37355, 37356, 37357, 37358, 37359, 37368, 37369, 37362, 37363, 37364, 37367, 37343, 37371, 37372, 37373, 'ProcessWFCObject', 37155, 37156, 37365, 37366, 36915, 36968, 36969, 36970, 36971, 36972, 36973, 36974, 36975, 36911, 36946, 36947, 36951, 36952, 36953, 36954, 36959]
EventsSupported = ['RequestObjectTransfer', 'StoreAdded', 'StoreRemoved', 'ObjectRemoved', 'ObjectAdded', 'ObjectInfoChanged', 49409]
DevicePropertiesSupported = [53321, 'DeviceFriendlyName', 'PerceivedDeviceType', 'SessionInitiatorVendorInfo', 54019, 'BatteryLevel']
CaptureFormats = ['EXIF_JPEG']
ImageFormats = ['Association', 'Script', 'DPOF', 'AVI', 'WAV', 'EXIF_JPEG', 45313, 45315, 48898, 'UndefinedImage', 45316, 45317]
Manufacturer = Canon Inc.
Model = Canon EOS 6D
DeviceVersion = 3-1.1.6
SerialNumber = 36f3cbc6d264f18
Container:
TransactionID = 0
SessionID = 2
ResponseCode = OK
Parameter = ListContainer:
Container:
TransactionID = 1
SessionID = 2
ResponseCode = SessionNotOpen
Parameter = ListContainer:
What am I doing wrong?
I installed sequoia-ptpy via pip, ran
from ptpy import PTPy
camera = PTPy()
and got
E 159369 ptpy.transports.usb[EvtPolling:__poll_events:582] <DEVICE ID 04a9:32c0 on Bus 000 Address 001> polling exception: a bytes-like object is required, not 'str'
E 160941 ptpy.transports.usb[EvtPolling:__poll_events:582] <DEVICE ID 04a9:32c0 on Bus 000 Address 001> polling exception: a bytes-like object is required, not 'str'
E 162515 ptpy.transports.usb[EvtPolling:__poll_events:582] <DEVICE ID 04a9:32c0 on Bus 000 Address 001> polling exception: a bytes-like object is required, not 'str'
Please advice
--Seeelefant
Trying the example, I can successful get the device info but then get "usb.core.USBError: [Errno 32] Pipe error" when camera.initiate_capture() is executed. Any hints what might go wrong there?
Hi!
Is there a discussion forum? Do not like to post an issue report each time I have a suggestion.
I have a strange problem with Canon DSLRs and gphoto2 as well as with PTPy. After some shots the device does not react anymore. Gphoto is very complex and not easy to debug. With PTPy I am able to reproduce and debug this behavior and it seems to be dangling sessions.
To reproduce :
with camera.session():
# The open session and close sessions operations are called
# in the background as needed.
print(camera.get_device_info())
# Allow remote shutter release.
print( camera.eos_set_remote_mode(1))
# Actual shutter release
print( camera.eos_remote_release())
<Terminate process here: kill -9>
This leads to a dangling session (ID=2). Rerunning the code yields only SessionNotOpen messages and capturing is no longer possible. Manual rebooting of the camera seems the only cure ---
BUT if you insert a second camera.open_session() in front of the capture command you will get a session ID=3 that allows for capturing.
This weird behavior found me to have a closer look at your session code and the PTP Spezifikation.
def open_session(self):
self.__session += 1
self.__transaction = 1
ptp = Container(
OperationCode='OpenSession',
# Only the OpenSession operation is allowed to have a 0
# SessionID, because no session is open yet.
SessionID=0,
TransactionID=0,
Parameter=[self.__session]
)
response = self.mesg(ptp)
if response.ResponseCode == 'OK':
self.__session_open = True
return response
The comment stated that the first call to OpenSession should be performed with a session ID of zero but the Spezification reads the opposite:
PIMA 15740: 2000
9.2.1 SessionID
Each session shall have a SessionID that consists of one device-unique 32-bit unsigned
integer (UINT32). SessionIDs are assigned by the Initiator as a parameter to the
OpenSession operation, and must be non-zero.
I suppose that the philosophy behind the PTP SessionIDs is comparable to the one in e.g. IMAP.
Therefore I changed the code a bit
def open_session(self, session_id = None):
self.__session += 1
self.__transaction = 1
ptp = Container(
OperationCode='OpenSession',
# Only the OpenSession operation is allowed to have a 0
# SessionID, because no session is open yet.
SessionID= session_id or self.__session,
TransactionID=0,
Parameter=[self.__session]
)
response = self.mesg(ptp)
if response.ResponseCode == 'OK':
self.__session_open = True
else:
print('error opening session', response)
return response
def close_session(self, session_id = None):
ptp = Container(
OperationCode='CloseSession',
SessionID= session_id or self.__session,
TransactionID=self.__transaction,
Parameter=[]
)
response = self.mesg(ptp)
if response.ResponseCode == 'OK':
self.__session_open = False
return response
The additional session_id parameter are for testing purpose, only. Utilizing this code the procedure with interrupting the code before close_session is called does no longer stall the camera.
This is for sure a particular finding only true for my system and a canon 6D.
I also suggest to capsulize the sessions in a session class. Without isolating the sessions from each other there is no way to keep track of them. At the moment the sessionIDs are simply incremented. This works as long as the user does only uses really atomistic operations. But if a user needs long running tasks this will lead to problems sooner or later.
Trying to connect to my camera over ptp ip and receiving the following error:
E 7967 ptpy.ptp[MainThread:recv:801] 'str' object is not callable
Traceback (most recent call last):
File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1599, in <module>
globals = debugger.run(setup['file'], None, None, is_module)
File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1026, in run
pydev_imports.execfile(file, globals, locals) # execute the script
File "/Users/davidhopkins/Code/wifi/sequoia-ptpy/examples/download_all_images.py", line 6, in <module>
camera = ptpy.PTPy(transport=IPTransport, device='192.168.1.8', extension=Canon)
File "/Users/davidhopkins/Code/wifi/sequoia-ptpy/ptpy/__init__.py", line 135, in __new__
instance._obtain_the_knowledge()
File "/Users/davidhopkins/Code/wifi/sequoia-ptpy/ptpy/ptp.py", line 857, in _obtain_the_knowledge
self.__device_info = self.get_device_info()
File "/Users/davidhopkins/Code/wifi/sequoia-ptpy/ptpy/ptp.py", line 953, in get_device_info
response = self.recv(ptp)
File "/Users/davidhopkins/Code/wifi/sequoia-ptpy/ptpy/ptp.py", line 802, in recv
raise e
TypeError: 'str' object is not callable
I am using the following command:
camera = ptpy.PTPy(transport=IPTransport, device='192.168.1.8')
My camera is a Canon 6D, I have been able to connect over wifi using ptp ip with other libraries such as gphoto2. Let me know if there is any other information I can provide. Thanks!
I found the .send and .recv methods which seem to expect a container like this
ptp = Container(
OperationCode='Capture',
SessionID=self._session,
TransactionID=self._transaction,
Parameter=[]
)
How would I use this is the main application to send a simple test command? (as I do not have access to session id / tranasction id)
Is there any package installation other then pip install . or python setup.py install?
Because i keep having Import Error for package
LengthValueAdapter
BitField
Hello
below is a patch that allows to instantiate PTPy() with a string (camera name):
camera = PTPy('NIKON DSC D70')
without breaking the past behavior.
Thank you for this Python PTP implementation!
Markus Wildi
diff --git a/ptpy/transports/usb.py b/ptpy/transports/usb.py
index 7ee4c5f..12321ec 100644
--- a/ptpy/transports/usb.py
+++ b/ptpy/transports/usb.py
@@ -70,12 +70,16 @@ class USBTransport(object):
# and get the USB endpoints for the first one that works.
if device is None:
logger.debug('No device provided, probing all USB devices.')
- devs = [device] if (device is not None) else find_usb_cameras()
- for dev in devs:
- if self.__setup_device(dev):
- logger.debug('Found USB PTP device {}'.format(dev))
- break
+ for dev in find_usb_cameras():
+ if device is None:
+ if self.__setup_device(dev):
+ logger.debug('Found first USB PTP device {}'.format(dev))
+ break
+ elif device in usb.util.get_string(dev, dev.iProduct):
+ if self.__setup_device(dev):
+ logger.debug('Found named USB PTP device {}'.format(device))
+ break
else:
message = 'No USB PTP device found.'
logger.error(message)
Trigger script (and I believe others) occasionally exit with an error. The script executes properly, but a nasty error appears. Sample output:
greg@ubuntu:/micasense/sequoia-ptpy/examples$ python trigger.py/micasense/sequoia-ptpy/examples$ python trigger.py
Exception in thread Thread-2 (most likely raised during interpreter shutdown):
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
File "/usr/lib/python2.7/threading.py", line 763, in run
File "build/bdist.linux-x86_64/egg/ptpy/transports/usb.py", line 380, in __poll_events
File "build/bdist.linux-x86_64/egg/ptpy/transports/usb.py", line 255, in __recv
<type 'exceptions.AttributeError'>: 'NoneType' object has no attribute 'core'
greg@ubuntu:
greg@ubuntu:/micasense/sequoia-ptpy/examples$ python trigger.py/micasense/sequoia-ptpy/examples$ python trigger.py
greg@ubuntu:
greg@ubuntu:/micasense/sequoia-ptpy/examples$ python trigger.py/micasense/sequoia-ptpy/examples$ python trigger.py
greg@ubuntu:
greg@ubuntu:/micasense/sequoia-ptpy/examples$ python trigger.py/micasense/sequoia-ptpy/examples$ python trigger.py
greg@ubuntu:
greg@ubuntu:/micasense/sequoia-ptpy/examples$ python trigger.py/micasense/sequoia-ptpy/examples$ python trigger.py
greg@ubuntu:
Exception in thread Thread-2 (most likely raised during interpreter shutdown):
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
File "/usr/lib/python2.7/threading.py", line 763, in run
File "build/bdist.linux-x86_64/egg/ptpy/transports/usb.py", line 380, in __poll_events
File "build/bdist.linux-x86_64/egg/ptpy/transports/usb.py", line 255, in __recv
<type 'exceptions.AttributeError'>: 'NoneType' object has no attribute 'core'
greg@ubuntu:~/micasense/sequoia-ptpy/examples$
Raspberry pi:
pi@raspberrypi:/sequoia-ptpy/examples $ python trigger.py/sequoia-ptpy/examples $ python trigger.py
pi@raspberrypi:
pi@raspberrypi:/sequoia-ptpy/examples $ python trigger.py/sequoia-ptpy/examples $ python trigger.py
Unhandled exception in thread started by <bound method Thread.__bootstrap of <Thread(Thread-2, stopped daemon 1976824928)>>
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 783, in __bootstrap
pi@raspberrypi:
Exception in thread Thread-2 (most likely raised during interpreter shutdown):
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
File "/usr/lib/python2.7/threading.py", line 763, in run
File "build/bdist.linux-armv7l/egg/ptpy/transports/usb.py", line 380, in __poll_events
File "build/bdist.linux-armv7l/egg/ptpy/transports/usb.py", line 255, in __recv
<type 'exceptions.AttributeError'>: 'NoneType' object has no attribute 'core'
pi@raspberrypi:~/sequoia-ptpy/examples $ python trigger.py
Exception in thread Thread-2 (most likely raised during interpreter shutdown):
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
File "/usr/lib/python2.7/threading.py", line 763, in run
File "build/bdist.linux-armv7l/egg/ptpy/transports/usb.py", line 380, in __poll_events
File "build/bdist.linux-armv7l/egg/ptpy/transports/usb.py", line 255, in __recv
<type 'exceptions.AttributeError'>: 'NoneType' object has no attribute 'core'
Hello,
How do I create an extension for Ricoh Theta Z1 camera in this package? Can anyone guide me through the changes that I need to make?
Hoping to hear a solution soon.
Trying this with my iOS 10.2 device (iPhone 6, just updated), I see this error:
>>> from ptpy import PTPy
>>> camera = PTPy()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/site-packages/ptpy/__init__.py", line 64, in __new__
device_info = plain_camera.get_device_info()
File "/usr/local/lib/python2.7/site-packages/ptpy/ptp.py", line 977, in get_device_info
response = self.recv(ptp)
File "/usr/local/lib/python2.7/site-packages/ptpy/transports/usb.py", line 342, in recv
self.__send_request(ptp_container)
File "/usr/local/lib/python2.7/site-packages/ptpy/transports/usb.py", line 320, in __send_request
self.__send(ptp)
File "/usr/local/lib/python2.7/site-packages/ptpy/transports/usb.py", line 295, in __send
transaction = self.__CommandTransaction.build(ptp_container)
File "/usr/local/lib/python2.7/site-packages/construct/core.py", line 212, in build
self.build_stream(obj, stream)
File "/usr/local/lib/python2.7/site-packages/construct/core.py", line 219, in build_stream
self._build(obj, stream, Container())
File "/usr/local/lib/python2.7/site-packages/construct/core.py", line 290, in _build
self.subcon._build(self._encode(obj, context), stream, context)
File "/usr/local/lib/python2.7/site-packages/construct/core.py", line 691, in _build
sc._build(subobj, stream, context)
File "/usr/local/lib/python2.7/site-packages/construct/core.py", line 273, in _build
self.subcon._build(obj, stream, context)
File "/usr/local/lib/python2.7/site-packages/construct/core.py", line 689, in _build
subobj = obj[sc.name]
KeyError: 'OperationsSupported'
>>> Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/local/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "/usr/local/lib/python2.7/threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "/usr/local/lib/python2.7/site-packages/ptpy/transports/usb.py", line 386, in __poll_events
evt = self.__recv(event=True, wait=False, raw=True)
File "/usr/local/lib/python2.7/site-packages/ptpy/transports/usb.py", line 274, in __recv
usbdata[0:self.__Header.sizeof()]
File "/usr/local/lib/python2.7/site-packages/construct/core.py", line 188, in parse
return self.parse_stream(BytesIO(data))
File "/usr/local/lib/python2.7/site-packages/construct/core.py", line 198, in parse_stream
return self._parse(stream, Container())
File "/usr/local/lib/python2.7/site-packages/construct/core.py", line 670, in _parse
subobj = sc._parse(stream, context)
File "/usr/local/lib/python2.7/site-packages/construct/core.py", line 288, in _parse
return self._decode(self.subcon._parse(stream, context), context)
File "/usr/local/lib/python2.7/site-packages/construct/adapters.py", line 104, in _decode
obj, self.subcon.name))
MappingError: no decoding mapping for 34817 [Type]
The event function in usb.py has the option to be called with a wait parameter. When set to True the event function should wait for and event to be queued if there's no event in the event queue. Unfortunately the event function does not respond appropriately when the wait parameter is set to True. It just goes it's merry way. Here is the function:
def event(self, wait=False):
'''Check event.
If `wait` this function is blocking. Otherwise it may return None.
'''
evt = None
usbdata = None
if not self.__event_queue.empty():
usbdata = self.__event_queue.get(block=not wait)
if usbdata is not None:
evt = self.__parse_response(usbdata)
return evt
The line 'usbdata = self.__event_queue.get(block=not wait)' will never execute if the queue is empty so it will never a blocking get. A better approach is this:
if wait:
usbdata = self.__event_queue.get(block=True)
elif not self.__event_queue.empty():
usbdata = self.__event_queue.get(block=False)
I have a CANON EOS 2000D.
I have tried the following implementation in canon.py:
def eos_init_viewfinder(self):
ptp = Container(
OperationCode='EOSInitiateViewfinder',
SessionID=self._session,
TransactionID=self._transaction,
Parameter=[]
)
return self.mesg(ptp)
This returns a SessionNotOpen
ResponseCode.
Can you give an example, how I can activate and deactivate the viewfinder?
I have also tried to get a viewfinder image. I have used the following short script.
camera = PTPy()
with camera.session():
print('hello')
result = camera.eos_get_viewfinder_image()
print('hello')
I set a breakpoint at the first print('hello'). Then I enable the viewfinder at the camera itself. Then I let the program continue.
In the result the Data
variable is empty.
Is the implementation missing?
I have also tried to get and set the parameter EVFMode=0xD1B1
. I have had no success.
Can you provide more examples on how to set or get CANON specific properties?
Sorry for the noobish questions. I have no experience with CANON PTP.
Thanks for your help.
Trying to use this with a Ricoh Theta Z1 on MacOS 10.13.6 and getting an Operation timed out error. I am able to connect with libusb--any ideas?:
[env] [11Jun2019 8:58:22][/dev/env]:python
Python 2.7.10 (default, Oct 6 2017, 22:29:07)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from ptpy import PTPy
>>> camera = PTPy()
E 8448 ptpy.transports.usb[EvtPolling:__recv:350] [Errno 60] Operation timed out
E 8448 ptpy.transports.usb[EvtPolling:__poll_events:575] <DEVICE ID 05ca:036d on Bus 000 Address 030> polling exception: [Errno 60] Operation timed out
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/dev/env/lib/python2.7/site-packages/ptpy/__init__.py", line 135, in __new__
instance._obtain_the_knowledge()
File "/dev/env/lib/python2.7/site-packages/ptpy/ptp.py", line 863, in _obtain_the_knowledge
self.__prop_desc[p] = self.get_device_prop_desc(p)
File "/dev/env/lib/python2.7/site-packages/ptpy/ptp.py", line 1059, in get_device_prop_desc
result = self._parse_if_data(response, self._DevicePropDesc)
File "/dev/env/lib/python2.7/site-packages/ptpy/ptp.py", line 824, in _parse_if_data
if hasattr(response, 'Data') else None)
File "/dev/env/lib/python2.7/site-packages/construct/core.py", line 175, in parse
return self.parse_stream(BytesIO(data), context, **kw)
File "/dev/env/lib/python2.7/site-packages/construct/core.py", line 186, in parse_stream
return self._parse(stream, context, "parsing")
File "/dev/env/lib/python2.7/site-packages/construct/core.py", line 859, in _parse
subobj = sc._parse(stream, context, path)
File "/dev/env/lib/python2.7/site-packages/construct/core.py", line 2700, in _parse
raise e.__class__("%s\n %s" % (e, path))
construct.core.RangeError: could not read prefix or enough elements, stream too short?
parsing -> FactoryDefaultValue
>>> E 9480 ptpy.transports.usb[EvtPolling:__recv:350] [Errno 60] Operation timed out
E 9480 ptpy.transports.usb[EvtPolling:__poll_events:575] <DEVICE ID 05ca:036d on Bus 000 Address 030> polling exception: [Errno 60] Operation timed out
E 10482 ptpy.transports.usb[EvtPolling:__recv:350] [Errno 60] Operation timed out
E 10482 ptpy.transports.usb[EvtPolling:__poll_events:575] <DEVICE ID 05ca:036d on Bus 000 Address 030> polling exception: [Errno 60] Operation timed out
E 11486 ptpy.transports.usb[EvtPolling:__recv:350] [Errno 60] Operation timed out
I'm trying to do image processing with OpenCV, and I am able to run the trigger example, but I don't want to save the image, I just want to store it in the code as e.g. an OpenCV Mat object for processing. What method do I call to get the stream?
Issue is described here: https://stackoverflow.com/questions/50605894/python-windows-7-importerror-cannot-import-name-x
where the file "USB transport.py" is the same as usb.py
I am running the following code:
from ptpy import PTPy
from ptpy.transports.ip import IPTransport
camera = PTPy(transport=IPTransport,device="192.168.156.1")
I get this error:
D 19 ptpy[MainThread:__new__:99] New PTPy
D 20 ptpy.ptp[MainThread:__init__:705] Init PTP
D 20 ptpy.ptp[MainThread:_set_endian:629] Set PTP endianness
D 21 ptpy.transports.ip[MainThread:__init__:77] Init IP
D 21 ptpy.transports.ip[MainThread:recv:600] RECV GetDeviceInfo
D 21 ptpy.transports.ip[MainThread:__setup_connection:194] Establishing PTP/IP connection with 192.168.156.1:15740
E 24 ptpy.transports.ip[MainThread:__implicit_session:115] <lambda>() takes exactly 3 arguments (2 given)
E 24 ptpy.ptp[MainThread:recv:801] Failed to open PTP/IP implicit session
Traceback (most recent call last):
File "test.py", line 3, in <module>
camera = PTPy(transport=IPTransport,device="192.168.156.1")
File "Experiments/sequoia-ptpy/ptpy/__init__.py", line 114, in __new__
device_info = plain_camera.get_device_info()
File "Experiments/sequoia-ptpy/ptpy/ptp.py", line 953, in get_device_info
response = self.recv(ptp)
File "Experiments/sequoia-ptpy/ptpy/ptp.py", line 802, in recv
raise e
ptpy.ptp.PTPError: Failed to open PTP/IP implicit session
This project would be a great addition to PyPI, are there any plans to host it there?
I am trying to run the camera control software ptpy 0.3.2
I am using window 10, python38.
I installed the software by pip install ptpy-0.3.2-py3-none-any.whl
From python, I execute the following commands:
from ptpy import PTPy
camera = PTPy()
I get the following error:
Traceback (most recent call last):
File "", line 1, in
File "D:\Python38\lib\site-packages\ptpy_init_.py", line 110, in new
plain_camera = plain(device=device)
File "D:\Python38\lib\site-packages\ptpy\ptp.py", line 712, in init
super(PTP, self).init(*args, **kwargs)
File "D:\Python38\lib\site-packages\ptpy\transports\usb.py", line 90, in init
else find_usb_cameras(name=name)
File "D:\Python38\lib\site-packages\ptpy\transports\usb.py", line 61, in find_usb_cameras
return usb.core.find(
File "D:\Python38\lib\site-packages\usb\core.py", line 1263, in find
raise NoBackendError('No backend available')
usb.core.NoBackendError: No backend available
In the python directory I have \site-packages\pyusb-1.0.2-py3.8.egg-info.
In site-packages\usb\backend I have libusb0.py, libusb1.py and openusb.py
In the Windows directory I only have only libusb0.dll in C:\Windows\System32\DriverStore\FileRepository\arduino_gemma.inf_amd64_ccc1c03de7b2c57b\amd64
In the locate_library function in D:\Python38\Lib\site-packages\usb\libloader.py, the find_library is ctypes.util.find_library
It is looking for the following DLLs:
usb-1.0.dll, libusb-1.0.dll, usb.dll, openusb.dll, usb-0.1.dll, libusb0.dll
I have also noticed that none of the above are in the Windows System32 directory. Should the code be modified to look for other DLLs?
I'm new to github and ptpy. Apologies if anything posted here is not in the correct format.
I'm trying to access my Nikon D800 camera using ptpy. I've installed a libusb-win32 driver (for the camera) and am running the example script from here under Python 3.
This is the output from the example script:
Please note I've added a print(i,device) around line 75 to the example script to see what info I'm getting from my camera.
I emailed Luis Domenzain and he suggested
"This looks like a PTPy bug under Python 3.
Please post an issue to GitHub for follow-up."
So that's what I'm doing :)
Thanks very much for any help you can give me on this one.
Steve C
PS I have tried other driver options from Zadig but I get similar errors in a seemingly infinite loop. This is the only driver option that (finally) exits with a code 0
Driver details:
Getting config items and triggering captures works properly with the camera, but when calling camera.event() I get the following error (after capturing an image).
Exception in thread EvtPolling:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "/home/pi/github/sequoia-ptpy/ptpy/transports/usb.py", line 457, in __poll_events
evt = self.__recv(event=True, wait=False, raw=True)
File "/home/pi/github/sequoia-ptpy/ptpy/transports/usb.py", line 307, in __recv
bytearray(usbdata[0:self.__Header.sizeof()])
File "/usr/local/lib/python2.7/dist-packages/construct/core.py", line 165, in parse
return self.parse_stream(BytesIO(data), context, **kw)
File "/usr/local/lib/python2.7/dist-packages/construct/core.py", line 176, in parse_stream
return self._parse(stream, context, "parsing")
File "/usr/local/lib/python2.7/dist-packages/construct/core.py", line 849, in _parse
subobj = sc._parse(stream, context, path)
File "/usr/local/lib/python2.7/dist-packages/construct/core.py", line 2713, in _parse
raise e.__class__("%s\n %s" % (e, path))
FieldError: packer '<L' error during parsing
parsing -> TransactionID
I would like to see support for an IP transport. Some platforms have issues in the USB layer so removing dependency on pyusb would be great.
Installing via Pip from Pypi yields
Processing /home/niklas/Downloads/ptpy-0.2.0.tar.gz
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/pip/download.py", line 421, in get_file_content
with open(url, 'rb') as f:
FileNotFoundError: [Errno 2] No such file or directory: 'requirements.txt'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/tmp/pip-tycta6yg-build/setup.py", line 11, in <module>
for r in parse_requirements('requirements.txt', session=False)
File "/tmp/pip-tycta6yg-build/setup.py", line 10, in <listcomp>
str(r.req)
File "/usr/local/lib/python3.5/dist-packages/pip/req/req_file.py", line 84, in parse_requirements
filename, comes_from=comes_from, session=session
File "/usr/local/lib/python3.5/dist-packages/pip/download.py", line 425, in get_file_content
'Could not open requirements file: %s' % str(exc)
pip.exceptions.InstallationError: Could not open requirements file: [Errno 2] No such file or directory: 'requirements.txt'
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.