Line 1: |
Line 1: |
| + | [[Category:ProductOpener]] [[Category:API]] |
| == Summary == | | == Summary == |
| | | |
Line 25: |
Line 26: |
| * <code>nutrition_data_per</code>: <code>100g</code> or <code>serving</code> | | * <code>nutrition_data_per</code>: <code>100g</code> or <code>serving</code> |
| * <code>serving_size</code>: (optional, but very useful, in particular if the nutrition facts are specified per serving) | | * <code>serving_size</code>: (optional, but very useful, in particular if the nutrition facts are specified per serving) |
− | * for each nutrient: | + | * For each nutrient: |
| ** <code>{nutrient-id}</code> (e.g. <code>saturated-fat</code>, <code>energy-kcal</code>): value for the nutrient, for the size specified in the field <code>nutrition_data_per</code>. This is a string made of the modifier ("<", ">" or "") and the value without unit ("17.8", "34,7", "< 0.1", etc). | | ** <code>{nutrient-id}</code> (e.g. <code>saturated-fat</code>, <code>energy-kcal</code>): value for the nutrient, for the size specified in the field <code>nutrition_data_per</code>. This is a string made of the modifier ("<", ">" or "") and the value without unit ("17.8", "34,7", "< 0.1", etc). |
| ** <code>{nutrient-id}_unit</code> (e.g. saturated-fat_unit, energy-kcal_unit): the unit of the value passed (e.g. "g", "mg", "kcal", "kJ", "%", "") | | ** <code>{nutrient-id}_unit</code> (e.g. saturated-fat_unit, energy-kcal_unit): the unit of the value passed (e.g. "g", "mg", "kcal", "kJ", "%", "") |
Line 31: |
Line 32: |
| Notes about the energy fields: | | Notes about the energy fields: |
| * Energy on labels can be written in kcal, kJ or both | | * Energy on labels can be written in kcal, kJ or both |
− | * when the energy is written in both, there is no simple conversion ratio between kcal and kJ | + | * When the energy is written in both, there is no universally defined conversion ratio between kcal and kJ. |
| ** This is because labelling laws in EU, US, CA etc. specify that the energy fields can (or must) be computed by multiplying and summing values for carbohydrates, proteins, fat etc. | | ** This is because labelling laws in EU, US, CA etc. specify that the energy fields can (or must) be computed by multiplying and summing values for carbohydrates, proteins, fat etc. |
| ** That's why we now store 2 energy fields, and not just one | | ** That's why we now store 2 energy fields, and not just one |
− | ** see https://esha.com/calorie-calculation-country/ for details | + | ** See https://esha.com/calorie-calculation-country/ for details |
− | * energy-kj and energy-kcal are the identifiers (nutrient-id) of the "Energy in kJ" and "Energy in kcal" fields. | + | * <code>energy-kj</code> and <code>energy-kcal</code> are the identifiers (<code>{nutrient-id}</code>) of the "Energy in kJ" and "Energy in kcal" fields. |
− | * old apps used to pass energy (as we had only one energy field instead of energy-kcal + energy-kj) | + | * Old apps used to pass energy (as we had only one energy field instead of energy-kcal + energy-kj) |
− | ** for those apps, the energy_unit field is used to populate the corresponding energy-kj or energy-kcal field | + | ** For those apps, the <code>energy_unit</code> field is used to populate the corresponding <code>energy-kj</code> or <code>energy-kcal</code> field |
| | | |
| ==== Fields entered and computed by the OFF backend (Product Opener) ==== | | ==== Fields entered and computed by the OFF backend (Product Opener) ==== |
| | | |
− | * nutrient-id_value : what was entered and passed in the nutrient-id field | + | * <code>{nutrient-id}_value</code>: what was entered and passed in the nutrient-id field. |
− | * nutrient-id_unit : what was entered and passed in the nutrient-id_unit field | + | * <code>{nutrient-id}_unit</code>: what was entered and passed in the nutrient-id_unit field. |
− | * nutrient-id : the value converted in the default unit (currently kJ for all energy fields (including energy-kcal), otherwise gram) | + | * <code>{nutrient-id}</code>: the value converted in the default unit (currently kJ for all energy fields (including energy-kcal), otherwise gram). |
− | * nutrient-id_[value of nutrition_data_per) is set to nutrient-id (e.g. if nutrition_data_per is "100g", the value of sugars_100g is set to the value of sugars | + | * <code>{nutrient-id}_(100g|serving)</code>: is set to <code>{nutrient-id}</code> (e.g. if <code>nutrition_data_per = 100g</code>, the value of <code>sugars_100g</code> is set to the value of sugars. |
− | * if the serving size is known, we compute the value for the other field (nutrient-id_100g or nutrient-id_serving) in default unit | + | * If the serving size is known, we compute the value for the other field (nutrient-id_100g or nutrient-id_serving) in default unit. |
| + | * The value of <code>energy_(100g|serving)</code> is calculated from <code>energy-kJ_(100g|serving)</code> if available, otherwise it is calculated from <code>energy-kcal}_(100g|serving)</code>. This field is in <code>kJ</code>. Note however that the kJ and kcal can be different according to the regulation, so do not assume a factor of 4.2 between the values. |
| | | |
| === Data display === | | === Data display === |
| | | |
− | The OFF web site, and apps, should only use these OFF proocessed fields to display the nutrition data: | + | The OFF web site, and apps, '''should only use these OFF processed fields''' to display the nutrition data: |
| | | |
− | * nutrient-id_100g or nutrient-id_serving (depending on the value of nutrition_data_per) : value in g or in kJ. The values are passed as float/double??? | + | * <code>{nutrient-id}_100g</code> or <code>{nutrient-id}_serving</code> (depending on the value of the value of <code>nutrition_data_per</code>): value in g or in kJ. The values are passed as float/double??? |
− | * nutrient-id_value : to show the original entered/passed data (useful for characters as "<" or "~"}. | + | * <code>{nutrient-id}_modifier</code> to get the value modifier ("<", ">", "~") |
| + | * <code>{nutrient-id}_value</code>: to show the original entered/passed data. |
| | | |
− | The web site and apps must: | + | The web site and apps '''must''': |
− | * indicate if the nutrition facts are per 100g or per serving. | + | * Indicate if the nutrition facts are per 100g or per serving. |
− | * convert the value in g or in kJ to the desired unit. | + | * Convert the value from g or kJ to the desired unit. |
| | | |
| Notes: | | Notes: |
− | * Don't use the nutrient-id_value and nutrient-id_unit fields | + | * Don't use the <code>{nutrient-id}_value</code> and <code>{nutrient-id}_unit</code> fields |
− | ** The nutrient-id may be empty as some apps don't pass a unit, and we use a default unit for the field | + | ** The <code>{nutrient-id}</code> may be empty as some apps don't pass a unit, and we use a default unit for the field |
| ** The value may be per 100g or per serving | | ** The value may be per 100g or per serving |
| | | |
Line 69: |
Line 72: |
| (What does this mean? only allow editing of the off processed field)??? | | (What does this mean? only allow editing of the off processed field)??? |
| | | |
− | == Possible improvements to make thing (a bit) simpler == | + | == Possible improvements to make things (a bit) simpler == |
| | | |
− | * In the API, rename the "nutrient-id" fields (such as energy-kj, saturated-fat) to "nutrient-id_value", so that it matches the name of the field stored. It also makes clearer where the value is coded. | + | * In the API, rename the <code>{nutrient-id}</code> fields (such as <code>energy-kj</code>, <code>saturated-fat</code>) to <code>{nutrient-id}_value</code>, so that it matches the name of the field stored. It also makes clearer where the value is coded. |
− | * Store the energy-kcal values in kcal, without converting them to kJ | + | * Store the <code>energy-kcal</code> values in kcal, without converting them to kJ |
| ** This is probably what people intuitively expect | | ** This is probably what people intuitively expect |
| ** It removes unnecessary conversions from kcal to kJ and back (which is not trivial, as some people/apps may choose a different conversion factor, such as 4.2 or 4.185) | | ** It removes unnecessary conversions from kcal to kJ and back (which is not trivial, as some people/apps may choose a different conversion factor, such as 4.2 or 4.185) |
| ** This would be a breaking change if some apps use the energy-kcal_100g/serving or energy-kj_100g/serving fields | | ** This would be a breaking change if some apps use the energy-kcal_100g/serving or energy-kj_100g/serving fields |
| + | * Expose only the recommended fields (see [[Nutrients_handling_in_Open_Food_Facts#Data_display|data display]]) |
| | | |
− | == Possible improvements to make thing (a bit) more complex == | + | == Possible improvements to make things (a bit) more complex == |
| | | |
| The current API does not allow to store values for the prepared product, but it can be done on the OFF web site. | | The current API does not allow to store values for the prepared product, but it can be done on the OFF web site. |
Line 86: |
Line 90: |
| | | |
| e.g. saturated-fat_prepared_100g, saturated-fat_prepared_value etc. | | e.g. saturated-fat_prepared_100g, saturated-fat_prepared_value etc. |
| + | == Documentation == |
| + | * [https://blog.trustwell.com/calorie-calculation-country How calories are calculated in different countries]. |
| + | * [https://eur-lex.europa.eu/legal-content/EN/TXT/HTML/?uri=CELEX:32011R1169&from=FR%20Appendix%20XIV#d1e32-62-1 Energy calculation in the EU] |