How to get the USB information like Manufacture Name, Size etc?
I am using Ubuntu 16.
and Python 2.7.12
Have you tried something like this :
busses = usb.busses()
for bus in busses:
devices = bus.devices
for dev in devices:
print (repr(dev))
print("manufacturer", dev.iManufacturer)
print("Size", dev.iSize)
NOTE : I think it will work only when you are connected one usb at a time
with this you can print all USB String Descriptors in pyusb : Manufacturer String Descriptor, Product String Descriptor, Serial Number String Descriptor ( for all USB devices, including the host controllers ) cf https://www-user.tu-chemnitz.de/~heha/viewchm.php/hs/usb.chm/usb5.htm
import usb
busses = usb.busses()
for bus in busses:
devices = bus.devices
for dev in devices:
manufacturer = usb.util.get_string(dev.dev, dev.dev.iManufacturer)
print str(manufacturer)
product = usb.util.get_string(dev.dev, dev.dev.iProduct)
print str(product)
serialnumber = usb.util.get_string(dev.dev, dev.dev.iSerialNumber)
print str(serialnumber)
print('\n')
you have to call this as root / with sudo else you get ValueError: The device has no langid error
other USB attributes you can print with their names :
import usb
busses = usb.busses()
for bus in busses:
devices = bus.devices
for dev in devices:
print " Device class:",dev.dev.bDeviceClass
print " Device sub class:",dev.dev.bDeviceSubClass
print " Device protocol:",dev.dev.bDeviceProtocol
Related
I need all connected bluetooth devices to my computer.
I found library, but i can't get connected devices
Simple inquiry example:
import bluetooth
nearby_devices = bluetooth.discover_devices(lookup_names=True)
print("Found {} devices.".format(len(nearby_devices)))
for addr, name in nearby_devices:
print(" {} - {}".format(addr, name))
The snippet of code in the question is doing a scan for new devices rather than reporting on connected devices.
The PyBluez library is not under active development so I tend to avoid it.
BlueZ (the Bluetooth stack on Linux) offers a set of API's through D-Bus that are accessible with Python using D-Bus bindings. I prefer pydbus for most situations.
The BlueZ API is documented at:
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/adapter-api.txt
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/device-api.txt
As an example of how to implement this in Python3:
import pydbus
bus = pydbus.SystemBus()
adapter = bus.get('org.bluez', '/org/bluez/hci0')
mngr = bus.get('org.bluez', '/')
def list_connected_devices():
mngd_objs = mngr.GetManagedObjects()
for path in mngd_objs:
con_state = mngd_objs[path].get('org.bluez.Device1', {}).get('Connected', False)
if con_state:
addr = mngd_objs[path].get('org.bluez.Device1', {}).get('Address')
name = mngd_objs[path].get('org.bluez.Device1', {}).get('Name')
print(f'Device {name} [{addr}] is connected')
if __name__ == '__main__':
list_connected_devices()
I found a solution, but it uses terminal.
Before using you need to install dependencies
Bluez
Code
def get_connected_devices():
bounded_devices = check_output(['bt-device', '-l']).decode().split("\n")[1:-1]
connected_devices = list()
for device in bounded_devices:
name = device[:device.rfind(' ')]
#mac_address regex
regex = '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})|([0-9a-fA-F]{4}\\.[0-9a-fA-F]{4}\\.[0-9a-fA-F]{4})$'
mac_address = re.search(regex, device).group(0)
device_info = check_output(['bt-device', '-i', mac_address]).decode()
connection_state = device_info[device_info.find('Connected: ') + len('Connected: ')]
if connection_state == '1':
connected_devices.append({"name": name, "address": mac_address})
return connected_devices
For example, I have connected to a LAN using the ethernet cable and to the internet using the WiFi. My computer has got 2 more interfaces that are currently not used.
The script should check for only active interfaces and return their IPs, router IPs, and the device names.
I would use netifaces. Like this:
import netifaces as ni
for iface in ni.interfaces():
print('interface : {0}'.format(iface))
try:
addrs = ni.ifaddresses(iface)
for k, v in addrs[ni.AF_INET][0].items():
print(' {0} : {1}'.format(k, v))
except:
pass
gways = ni.gateways()
print('gateway: {0}'.format(gways['default'][ni.AF_INET][0]))
First off if anybody knows of a good tutorial for coding bluetooth on my raspberry pi zero w with python to turn on discovery, listen for a pair request, connect and save the paired device, and more, that would be awesome. My code for testing bluetooth discovery is below.
import bluetooth
print("performing inquiry...")
nearby_devices = bluetooth.discover_devices(
duration=8, lookup_names=True, flush_cache=True)
print("found %d devices" % len(nearby_devices))
for addr, name in nearby_devices:
try:
print(" %s - %s" % (addr, name))
except UnicodeEncodeError:
print(" %s - %s" % (addr, name.encode('utf-8', 'replace')))
The TraceBack is below
Traceback (most recent call last):
File "bluetoothConnect.py", line 6, in <module>
duration=8, lookup_names=True, flush_cache=True)
File "/usr/lib/python2.7/dist-packages/bluetooth/bluez.py", line 17, in discover_devices
sock = _gethcisock ()
File "/usr/lib/python2.7/dist-packages/bluetooth/bluez.py", line 226, in _gethcisock
raise BluetoothError ("error accessing bluetooth device")
bluetooth.btcommon.BluetoothError: error accessing bluetooth device
("error accessing bluetooth device") is the clue.
Yes - as earlier mentioned you need elevated privileges.
Simply run the script with sudo...
eg - sudo python myscript.py
enter your password
It should now work..for testing purposes.
Though going forward I would create a privileged user and add that user to the root group with the setting /bin/false.
Then use that user to run all your scripts..
Had the same issue and then I wrote this simple script to wrap Bluetoothctl using python3. Tested on Raspberry pi 4.
import subprocess
import time
def scan(scan_timeout=20):
""" scan
Scan for devices
Parameters
----------
scan_timeout : int
Timeout to run the scan
Returns
----------
devices : dict
set of discovered devices as MAC:Name pairs
"""
p = subprocess.Popen(["bluetoothctl", "scan", "on"])
time.sleep(scan_timeout)
p.terminate()
return __devices()
def __devices():
""" devices
List discovered devices
Returns
----------
devices : dict
set of discovered devices as MAC:Name pairs
"""
devices_s = subprocess.check_output("bluetoothctl devices", shell=True).decode().split("\n")[:-1]
devices = {}
for each in devices_s:
devices[each[7:24]] = each[25:]
return devices
def info():
""" Info
Returns
----------
info : str
information about the device connected currently if any
"""
return subprocess.check_output("bluetoothctl info", shell=True).decode()
def pair(mac_address):
""" pair
Pair with a device
Parameters
----------
mac_address : str
mac address of the device tha you need to pair
"""
subprocess.check_output("bluetoothctl pair {}".format(mac_address), shell=True)
def remove(mac_address):
""" remove
Remove a connected(paired) device
Parameters
----------
mac_address : str
mac address of the device tha you need to remove
"""
subprocess.check_output("bluetoothctl remove {}".format(mac_address), shell=True)
def connect(mac_address):
""" connect
Connect to a device
Parameters
----------
mac_address : str
mac address of the device tha you need to connect
"""
subprocess.check_output("bluetoothctl connect {}".format(mac_address), shell=True)
def disconnect():
""" disconnect
Disconnects for currently connected device
"""
subprocess.check_output("bluetoothctl disconnect", shell=True)
def paired_devices():
""" paired_devices
Return a list of paired devices
"""
return subprocess.check_output("bluetoothctl paired-devices", shell=True).decode()
Note: This is Python 2.7 and PyUSB 0.4.3
I am trying to send serial data from an Arduino Yun to a USB dongle plugged into the Yun's USB host port using a Python script. The data is just a sequence of characters (currently just one to simplify debugging). Here is the script, the data to be written is the character 'W':
import usb
busses = usb.busses()
for bus in busses:
devs = bus.devices
for dev in devs:
if dev.idVendor == 9304 and dev.idProduct == 1:
d = dev
conf = d.configurations[0]
intf = conf.interfaces[0][0]
endpoints = []
for endpoint in intf.endpoints:
endpoints.append(endpoint)
endpoint = endpoints[0]
handle = d.open()
handle.interruptWrite(0, 'W')
This is the error:
Traceback (most recent call last):
File "ser_test.py", line 21, in <module>
handle.interruptWrite(0, 'W')
usb.USBError: error submitting URB: No such file or directory
I have tried 0-1000 for the first argument with no luck. What is the proper way to write this to send a 'W' character from the host to the dongle? I've read in other posts that PyUSB is only a set of wrappers for usblib, but haven't been able to find an answer in the usblib documentation.
Here is the output of lsusb (dongle is 2458:0001):
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 058f:6254 Alcor Micro Corp. USB Hub
Bus 001 Device 003: ID 2458:0001
Bus 001 Device 004: ID 058f:6366 Alcor Micro Corp. Multi Flash Reader
Thanks.
For test purposes, I want to connect a USB device and want to check what is the speed (HS/FS/LS).
I am able to access to Device Descriptor, Endpoint descriptor, interface descriptor but I would like to know the device address which has been allocated by the OS (windows 7)
My code so far :
import usb
busses = usb.busses()
for bus in busses:
for dev in bus.devices:
if dev.idVendor == vendor_id and dev.idProduct == product_id:
print ("Test vehicle %s device FOUND!" %protocol)
print ("iManufacturer : %s" %usb.util.get_string(dev.dev, 256, 1))
print ("iProduct : %s" %usb.util.get_string(dev.dev, 256, 2))
print ("iSerialNumber : %s" %usb.util.get_string(dev.dev, 256, 3))
return dev
print ("Test vehicle %s device NOT FOUND!" %protocol)
Returns :
C:\Python27\Lib\site-packages>python example.py
Test vehicle HS device FOUND!
iManufacturer : Kingston
iProduct : DataTraveler 2.0
iSerialNumber : 5B720A82364A
In the very useful USBview software, there is a section :
ConnectionStatus: DeviceConnected
Current Config Value: 0x01
Device Bus Speed: High
Device Address: 0x09
Open Pipes: 2
How do I get these informations ? is it a query to the USB device using pyUSB ? or is it a query to sys ?
Thanks for any help.
There are several more fields available in the device objects (in your code these are named dev).
A quick and dirty way to look at them
def print_internals(dev):
for attrib in dir(dev):
if not attrib.startswith('_') and not attrib == 'configurations':
x=getattr(dev, attrib)
print " ", attrib, x
for config in dev.configurations:
for attrib in dir(config):
if not attrib.startswith('_'):
x=getattr(config, attrib)
print " ", attrib, x
And call it within your "for dev in bus.devices" loop. It looks like the filename might correspond to 'device address', though bus speed is a bit deeper in (dev.configurations[i].interfaces[j][k].interfaceProtocol), and this only has an integer. usb.util might be able to provide you more information based on those integers, but I don't have that module available to me.
Documentation for pyUSB doesn't seem to be very extensive, but this SO question points at the libusb docs which it wraps up.
You can get usb device speed information by pyUSB with this patch https://github.com/DeliangFan/pyusb/commit/a882829859cd6ef3c91ca11870937dfff93fea9d.
Because libusb1.0 has already support to get usb speed information.
These attributes are (nowadays) easily accessible. At least it works for me. https://github.com/pyusb/pyusb/blob/master/usb/core.py
import usb.core
devices = usb.core.find(find_all=True)
dev = next(devices)
print("device bus:", dev.bus)
print("device address:", dev.address)
print("device port:", dev.port_number)
print("device speed:", dev.speed)