Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Barcode support #865

Merged
merged 22 commits into from
Jun 12, 2020
Merged

Conversation

SchrodingersGat
Copy link
Member

Beginnings of wedge-scanner support

@rco3 you might find this interesting ;)

Ref: #853

@SchrodingersGat
Copy link
Member Author

image

image

image

@rco3
Copy link

rco3 commented Jun 12, 2020

I salivate.

Also, I talked about the Digikey barcode validate in the other thread. Sorry. I'll keep it here.

@SchrodingersGat
Copy link
Member Author

Added a global "scan barcode" button, which allows barcode lookup and browser redirect to the relevant page:

image

image

@SchrodingersGat SchrodingersGat merged commit a632194 into inventree:master Jun 12, 2020
@SchrodingersGat SchrodingersGat deleted the barcode-suppor branch June 12, 2020 07:57
@SchrodingersGat
Copy link
Member Author

@rco3 please pull down latest master and have a play around with the new barcode scanner functionality. I have tested a little bit here, but only using my phone as a "fake" wedge scanner.

This will all have to be documented, too. Currently there is zero instruction on how to use this.

@rco3
Copy link

rco3 commented Jun 15, 2020

Sorry, didn't see this comment.

I have been playing with the new barcode functionality. I have used my wired wedge, which does produce escape characters, to associate a DataMatrix barcode with a particular Stock Item. I scanned that same DM into the "scan Barcode" field, and it took me right to that Stock Item! I wet myself.

I notice that you're hashing the content - are you hashing all characters, or are you pulling out control codes first? As I have three different wedges that all return escaped characters differently, I'm wondering if that will break the mapping of barcode to barcode hash.

Now I really have to get that validate_datamatrix() method working. This is really shaping up, Oliver. Well done.

@SchrodingersGat
Copy link
Member Author

Currently the hash is just everything in the data.

Can you explain to me the difference in escape characters between your scanners?

@rco3
Copy link

rco3 commented Jun 16, 2020

Sure. [deep breath]

DataMatrix barcodes found on electronics packaging typically are formatted in the ECIA's Format06, in which the data are separated into fields using Group Separator characters. The ASCII value is 29, the hex value is 1D. One method I have returns this exact code.

(1) I have a Teemi T22 USB wired barcode scanner that returns '[)>06PYAG3365CT-ND' for the first chunk of a barcode on this particular package. The first weird thing is a Record Separator, the second one is a Group Separator. My hex editor decodes those as 'EF 9C 8C' and 'EF 9C 8B' respectively. In my Python code, I call

    def decode_DM(self, event):
        hdr = re.compile('([0-9]*[DJKLPQTVZ])')
        data = bytes(self.contents.get(), encoding='utf_8')
        if b'\xef\x9c\x8b' in data:
            fields = re.split(b'\xef\x9c[\x81-\x8e]', data)
            for item in fields:
                entry=hdr.split(str(item, encoding='utf8'),1)
                print(entry)

and get

['[)>']
['06']
['', 'P', 'YAG3365CT-ND']
['', '1P', 'RT1206FRE07100KL']
['', 'K', '']
['', '1K', '52907693']
['', '10K', '60548898']
['', '11K', '1']
['', '4L', '']
['', 'Q', '100']
['', '11Z', 'PICK']
['', '12Z', '5418070']
['', '13Z', '862411']
['', '20Z',

followed by a bunch of zeros to fill.

So, the Teemi makes decoding DataMatrix simple.

(2) I have a ScanAvenger BlueTooth 2D barcode scanner. It scans the same barcodes equally well, but it returns '[)>300629PYAG3365CT-ND' for the same chunk of DataMatrix. It dropped a literal '30' in place of the RS, ASCII character #30; same for 29 for the GS. That's a lot harder to definitively use for separating fields. Admittedly, much of this behavior is likely OS-specific; I'm willing to believe the (really nice) support folks (who I got to know quite well) when they tell me that it produces '[)>▲06↔' ('E2 96 B2' and 'E2 86 94') in their Win10 test systems, but since I don't use Windows 10 and I have a wired scanner that DOES produce escaped codes on my Mac, that doesn't really help me. I bought another Bluetooth 2D scanner but no more luck with it.

(3) @maholli's code using OpenCV and libdtmx produces '1E' and '1D', so he can split the fields with

fields = re.split('[\x1d-\x1e]', barcodeData.decode())

to get the same field separation I do, although he only looks for one field.

Each field has a prefix consisting of 0 or more digits of numeral followed by a consonant, so far always one of [DJKLPQTVZ], followed by the data content. In the case where we have '29' and '30' for our RS and GS, perhaps we can achieve a sufficiently high degree of confidence in searching for 29 followed by 0-2 digits followed by [DJKLPQTVZ] to establish field separations (can you tell I suck at regex?)

For a group or company which enforces homogeneity of scanners, the concern about RS,GS is moot: they'll all produce the same hash from the same scanner. For folks like me wanting to pre-populate fields from the DataMatrix as a vector for adding new Stock Items, it's a little trickier. We can just match the ['[)>']
['06'] parts with whatever in-between (up to 10 bytes, say) to verify it's a DataMatrix in Format06. Or, if it starts with '>[)>06' then it's a DataMatrix in Format06 and Mouser is the vendor. But if the stuff in between is '30' or something else indistinguishable from normal text... Well, I guess I'll use the wired scanner to import new data (or libdtmx) with their RS and GS, and use the handy Bluetooth scanners to associate the barcode with the stock item since it's just a hash.

Of course, they all produce the exact same content from Inventree QR codes... :-)

[exhales]

@rco3
Copy link

rco3 commented Jun 17, 2020

Hey, what if we generate a DataMatrix with RS and GS characters separated by known, easily-identified strings, scan it with the barcode wedge we're using, and thus identify the exact characters that a given scanner or library produces for them. Did I mention that of my two Bluetooth wedges, one puts out '30' and '29', and the other produces nothing and '029' for the same codes?

I'm banging away amateurishly on the process of extracting Fields Of Interest from DataMatrix. I'm currently at the point of being able to get a list of headers and fields (even from the above wedges), and I'll flail around trying to convert that into some sort of usable dict in which I associate the 1P field (Supplier Part Number per ECIA) with MPN (Manufacturer Part Number in Inventree). If it's a Newark DM, there may be a 3P field for SKU; DK puts SKU in the P field in all the packages I have... well, anyway.

What's the correct - most useful - way to package this data, assuming that I handle the minefield of the above? I would like to feed this into a New Stock Item process within Inventree that supports (where necessary) adding a new Part , Supplier Part, Supplier (if known), etc. from within this process, pre-populating whatever data we can from what I can extract. If I do it externally via Python API, I end up having to create selection menus for Categories, Supplier Part, Part, and all the other stuff that a human has to approve and decide... and that all already exists within Inventree. It almost all already exists from the Add Stock Item dialog, except for the Add Supplier which is not there. I'll create a new issue for that.

@ArakniD
Copy link

ArakniD commented Dec 24, 2020

What's the correct - most useful - way to package this data, assuming that I handle the minefield of the above? I would like to feed this into a New Stock Item process within Inventree that supports (where necessary) adding a new Part , Supplier Part, Supplier (if known), etc. from within this process, pre-populating whatever data we can from what I can extract. If I do it externally via Python API, I end up having to create selection menus for Categories, Supplier Part, Part, and all the other stuff that a human has to approve and decide... and that all already exists within Inventree. It almost all already exists from the Add Stock Item dialog, except for the Add Supplier which is not there. I'll create a new issue for that.

hey I’ve added zxing-js browser to my fork and updated the digikey barcode related files. It no auto adds parts, manufacturers, assigns supplier and adds a stock item for that part with your reference text..

Check it out and comment? It needs more work to import all the params, links, documents and images.

And to also auto assign the relevant categories and param templates...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants