openfoodfacts / openfoodfacts-server

Open Food Facts database, API server and web interface - 🐪🦋 Perl, CSS and JS coders welcome 😊 For helping in Python, see Robotoff or taxonomy-editor
http://openfoodfacts.github.io/openfoodfacts-server/
GNU Affero General Public License v3.0
657 stars 386 forks source link

🌅 GS1 "Sunrise 2027" - 2D Barcodes, GS1 Element String, and GS1 Digital Link URI support #8333

Closed hangy closed 8 months ago

hangy commented 1 year ago

What

ProductOpener and related apps should support 2D barcodes - more specifically "GS1 DataMatrix" and "GS1 QR Code".

This includes support for barcodes that contain the GTIN in more formats than the current barcode.

Support can be done in stage. For example, support for the AI 01 (GTIN) could be implemented first. Supporting additional information from the GS1 URI/GS1 data string has interesting opportunities, ie. when handling Variable Measure Trade Items for later stages, though.

Why

GS1 has plans to replace the current EAN/UPC barcodes by DataMatrix and QR Code barcodes to support storing more data in the barcode. Traditional and 2D barcodes will be used in parallel for a while after this, but GS1 apparently intends to stop issuing new non-2D codes starting 2027.

GS1 links

Who for

All users of ProductOpener, and other apps that scan product barcodes for use with ProductOpener.

### Tasks
- [ ] https://github.com/openfoodfacts/openfoodfacts-server/issues/8925
- [ ] https://github.com/openfoodfacts/openfoodfacts-server/issues/8926
- [ ] https://github.com/openfoodfacts/openfoodfacts-server/issues/9013
- [ ] https://github.com/openfoodfacts/openfoodfacts-server/issues/9048
stephanegigandet commented 1 year ago

We could either let the clients handle it, and tell them to send only the GTIN part, and continue to use that as the main "code" identifier.

Or better, we can let clients send the extra digits, so that we can use the GTIN part to get the product, and the other parts to update on the fly the quantity etc. for that particular product request.

For apps, there's an interesting test kit with all barcodes formats: https://www.gs1us.org/content/dam/gs1us/documents/industries-insights/standards/GS1-US-Barcode-Capabilities-Test-Kit-Version-1.pdf

hangy commented 1 year ago

I think there's some advantage to having clients send the full GS1 Digital Link URI, or the full GS1 element string. It can contain so much more information, which can be used to augment the existing data using the packaging date, expiration date, price. ProductOpener probably won't support all AIs in the beginning, but it could store distinct barcode variations to analyze the additional data later on.

search_or_add will need to support the different barcode types server-side at some point in time, too.

Gjermstad commented 1 year ago

IMG_5796 IMG_5797

In Norway several grocery stores have in the last half year started using the 2D barcodes. And I suddenly experienced yesterday that I couldn’t scan and add a micowave meal I bought since it doesn’t have a EAN barcode at all on the box.

Here is a translated article about it: https://e24-no.translate.goog/naeringsliv/i/8J7VmE/etter-50-aar-skal-strekkoden-byttes-ut-en-gamechanger-for-matsvinn?_x_tr_sl=no&_x_tr_tl=en&_x_tr_hl=no&_x_tr_pto=wapp

I hope the app will get the possibility to scan these 2D codes or a lot of meat and other products in Norway won’t be possible to add to OFF in the future 🫣

hangy commented 1 year ago

@Gjermstad 01070356200521631523080710230710 is the barcode I'm getting from most readers when scanning your image. Could you check if that's the same when you scan the barcode from the packaging directly? I'm wondering if it's just me having an issue scanning the image, or if it's another barcode format, which is distinct to the GS1 DataMatrix format described above.

Gjermstad commented 1 year ago

I'd like to try, but I have no idea how @hangy 😅

hangy commented 1 year ago

It should be possible to read the barcode with any typical barcode scanner app (ie. Barcode Scanner on F-Droid). You can usually just launch the app and point it at the barcode.

However, you don't have to. I did a bit more research, and it appears the the non-printable character in the beginning actually is "FNC1", a control character that marks the barcode as a GS1 DataMatrix code. This means that�01070356200521631523080710230710 is a GS1 DataMatrix code identifying the GTIN (01): 07035620052163, Best Before (15): 2023-08-07, Batch/Lot (10): 230710. My mistake was thinking that the content would contain the parenthesis, but those are just visual help, not part of the actual DataMatrix code.

Gjermstad commented 1 year ago

Cool. Sorry I'm a complete noob with Github and OFF so I'm just trying to learn here and I had never seen a barcode like this before 😅 Thank you taking the time to explain.

hangy commented 1 year ago

No worries, it's very valuable input already! 😄

On topic: I think it could be a good idea to wrap gs1-syntax-engine as a Perl module. That seems to be an official OSS C library from GS1 to help with the syntax.

hangy commented 1 year ago

I think it could be a good idea to wrap gs1-syntax-engine as a Perl module

Built a PoC for the wrapper: https://github.com/hangy/stunning-goggles

Basically, this allows one to pass a GS1 DataMatrix code (^ being the FNC1 control char) or GS1 Digital Link URI, and get an AI string back. That could then be used to a) store it in normalized form, and b) parse the AI string for (01) as the key indicator, and other values for weight, etc.

Tests: https://github.com/hangy/stunning-goggles/tree/147fc4ad78df816a5c69cf520d2333431fb833d8/t Example JS usage: https://github.com/gs1/gs1-syntax-engine/blob/7b4b933a512622a77825d27f62c8ea96485c140c/src/js-wasm/example.mjs#L107C1-L149C4

hangy commented 8 months ago

Nothing more to do for this on my short-term roadmap.