Using Python hidapi to open device with multiple usages - python

I'm new to the Python hidapi although I've used the C version that it is based on before. The Python library is really different and I can't figure out how to use it from the one example that is provided. Does anyone know of any good documentation for this library?
If you're looking for a specific question, I'm trying to open an HID device that has multiple usages. My device has the following relevant characteristics:
vendor_id: 10618
product_id: 4
usage: 8
usage_page: 1
interface_number: 1
I have tried using hid_enumerate to select the dictionary that I want but after instantiating the device object the device will not open even though I know it's there (since it is listed in enumerate).

Although I would still like to find some decent documentation, after using the C hidapi header for reference I found an answer to my original question. In order to specify the usage, you must use open_path() instead of the regular open() method (see below):
import hid
#Get the list of all devices matching this vendor_id/product_id
vendor_id = 10618
product_id = 4
device_list = hid.enumerate(vendor_id, product_id)
#Find the device with the particular usage you want
device_dict = (device in device_list if device['usage'] == '8').next()
device = hid.device()
device.open_path(device_dict['path']) #Open from path

Related

How to read data from ".data" section of a process?

So, as far as I understand from looking online, the .data section of the PE file contains the static and global variables of the program.
All I am trying to do is create a variable in Python, or write something in notepad.exe, and look it up in its memory using the Win32 API.
What I have done:
I looked into the PE file structure of notepad.exe and found the virtual address of its .data section.
I attached to the running process and found its base address, and then added the virtual address of the .data section to that (is this the right calculation? If not, I would appreciate any learning resources, as I couldn't find much).
I tried to read about 1000 bytes, and I found some data. But when looking for hello (in hex, of course), it didn't find anything.
For the sake of POC and simplicity, I am using the Pymem module to make the Win32 API calls.
Here is my code:
import pymem
import pefile
process = pymem.Pymem('Notepad.exe')
process_module = list(process.list_modules())[0]
pe = pefile.PE(process_module.filename)
data_section = [x for x in pe.sections if b'.data' in x.Name][0]
section_address = process_module.lpBaseOfDll + data_section.VirtualAddress
section_size_to_scan = data_section.section_max_addr - data_section.section_min_addr
mem_dump = process.read_bytes(section_address, section_size_to_scan)
hello_in_hex = b'\x68\x65\x6c\x6c\x6f'
print(mem_dump)
print(hello_in_hex in mem_dump)
Obviously, the output is False.
Does anyone knows where I am making a mistake?

Extract text from pdf to file

This question is probably a duplicate, but none of the answers in similar questions helped me. I'm looking for a simple way to extract text from a pdf file into any other type of file or structure which will let me use it.
the text I want to extract appears on pages 78-79.
At the end of the processes, I want to write each cell from the table in different rows in a .txt file. for example, I want to turn the first row in the table from this:
to this:
0x00
Channel standby
CH_7
CH_6
CH_5
CH_4
CH_3
CH_2
CH_1
CH_0
0x00
RW
I'm using Visual Studio 2017 but I can also work on Pycharm instead.
I've tried using all the options suggested in this question and here
but I'm having problems installing the required libraries on windows 10 OS. I'm also not sure whether those libraries are still in use and supported. I'd appreciate it if anyone could refer me to some updated material on this subject or refer me to the relevant library.
Thank you.
Here's something using PyMuPDF (pip install pymupdf).
In this example, get_document_bytes simply makes a request the PDF resource at the URL you provided (using the third-party requests module), and returns the PDF bytes. We use the bytes in main to create a fitz.Document instance via the stream parameter. You could also just download the PDF file manually and provide a filename instead of a stream of bytes, but I didn't feel like doing that. We grab a specific page from the document and print all the text on that page:
def get_document_bytes():
import requests
url = "https://www.mouser.co.il/datasheet/2/609/AD7768-7768-4-1502035.pdf"
headers = {
"user-agent": "Mozilla/5.0"
}
response = requests.get(url, headers=headers)
response.raise_for_status()
return response.content
def main():
import fitz
desired_page = 78
doc = fitz.Document(stream=get_document_bytes(), filetype="PDF")
page = doc.loadPage(page_id=desired_page-1)
print(page.getText())
return 0
if __name__ == "__main__":
import sys
sys.exit(main())
Output:
AD7768/AD7768-4
Data Sheet
Rev. B | Page 78 of 105
AD7768 REGISTER MAP DETAILS (SPI CONTROL)
AD7768 REGISTER MAP
See Table 63 and the AD7768-4 Register Map Details (SPI Control) section for the AD7768-4 register map and register functions.
Table 37. Detailed AD7768 Register Map
Reg.
Name
Bit 7
Bit 6
Bit 5
Bit 4
Bit 3
Bit 2
Bit 1
Bit 0
Reset RW
0x00
Channel standby
CH_7
CH_6
CH_5
CH_4
CH_3
CH_2
CH_1
CH_0
0x00
RW
...
I realize you want the text from two pages, not just one - and you also don't want all the text from these pages, just the stuff that's in the table. This is just to get you started - I may tinker around with this a bit more, and update my post later.

How can I display an empty staff using music21?

I am trying to produce a quick reworking of some educational materials on music showing how it may be able to create the associated media assets (images, audio files) from "code" in a Jupyter notebook using the Python music21 package.
It seems the simplest steps are the hardest. For example, how do I create an empty staff:
or a staff populated by notes but without a clef at the start?
If I do something like:
from music21 import *
s = stream.Stream()
s.append(note.Note('G4', type='whole'))
s.append(note.Note('A4', type='whole'))
s.append(note.Note('B4', type='whole'))
s.append(note.Note('C5', type='whole'))
s.show()
I get the following?
Try creating a stream.Measure object, so that barlines before the notes don't appear.
Music21 puts barlines and clefs, etc., in by default. You can manually put in a time signature of 4/1 and a treble clef and set them with ".style.hideObjectOnPrint" (or just ".hideObjectOnPrint" on older m21 versions). You will probably need to also set .rightBarline = bar.Barline('none') or something like that for the end.
It is possible, but I haven't ever fully tried all the parts of it.

GATT Characteristics with read-property not found by application

I am trying to develop an application that is communicating with an external device using BLE. I have decided to use pygatt (Python) with BGAPI (using a BlueGiga dongle).
The device I am communicating with has a custom primary service with a set of characteristics. According to their specs they have 2 READ characteristics, 8 NOTIFY chars and 1 WRITE char. Initially, I want to read one of the two READ chars, but I am unable to do so. Their UUIDs are not recognized as characteristics. How can this be? I am 100% certain that they are entered correctly.
import pygatt
import bleconnect
import blelib
import logging
logging.basicConfig()
logging.getLogger('pygatt').setLevel(logging.DEBUG)
adapter = pygatt.BGAPIBackend(serial_port='/dev/tty.usbmodem1')
adapter.start()
# Find the device
result = adapter.scan(timeout=5)
for item in result:
scan_name = item['name']
scan_rssi = item['rssi']
scan_address = item['address']
if scan_name == bleconnect.TARGET_NAME:
break
# Connect
device = adapter.connect(address=scan_address)
device.char_read(blelib.CHARACTERISTIC_DEVICE_FEATURES)
I can see in the debug messages that all the NOTIFY and WRITE characteristics are found, but not the two READ characteristics.
What am I missing?
This appears to be some kind of shortcoming in the pygatt API. I managed to find the actual value using bgapi only.

Get Serial Number of USB device with Python 3

I have been using pyusb to access the detail of a printer plugged in via USB. I currently have the following code working, but it appears that different devices require a different index. Here is my current code:
import usb
dev = usb.core.find(idProduct=0x001f)
print(usb.util.get_string(dev,256,3))
dev2 = usb.core.find(idProduct=0x0009)
print(usb.util.get_string(dev2,256,3))
The code for dev works perfectly, outputting a serial number, but dev2 outputs 'Zebra,' the manufacturer name. If I change 3 to either 6 or 7 it works, but then the first dev returns an error.
One solution in Python 2 is to use print(dev.serial_number), but in the serial_number attribute doesn't appear to exist in pyusb for Python 3.
Is there a way to get this working reliably for all devices? Thanks.
For the present PyUSB version 1.0.2, I found the correct syntax to answer this question to be:
import usb
dev = usb.core.find(idProduct=0x001f)
print( usb.util.get_string( dev, dev.iSerialNumber ) )
dev2 = usb.core.find(idProduct=0x0009)
print( usb.util.get_string( dev2, dev2.iSerialNumber ) )

Categories