From 5389ff3253fd612008b1723797e459b1c53e6885 Mon Sep 17 00:00:00 2001
From: epenet <6771947+epenet@users.noreply.github.com>
Date: Wed, 28 Sep 2022 12:13:49 +0200
Subject: [PATCH] Add new weight device class (#79185)

---
 .../components/recorder/statistics.py         |  3 +
 .../components/recorder/websocket_api.py      |  7 +++
 homeassistant/components/sensor/__init__.py   |  7 +++
 .../components/sensor/device_condition.py     |  2 +
 .../components/sensor/device_trigger.py       |  2 +
 homeassistant/components/sensor/recorder.py   |  2 +
 homeassistant/components/sensor/strings.json  |  6 +-
 .../components/sensor/translations/en.json    |  6 +-
 homeassistant/util/unit_conversion.py         | 33 ++++++++++
 tests/components/sensor/test_init.py          | 27 +++++++++
 tests/components/sensor/test_recorder.py      | 14 +++++
 tests/util/test_unit_conversion.py            | 60 +++++++++++++++++++
 12 files changed, 165 insertions(+), 4 deletions(-)

diff --git a/homeassistant/components/recorder/statistics.py b/homeassistant/components/recorder/statistics.py
index 8d679cbeae6..427bffb71dc 100644
--- a/homeassistant/components/recorder/statistics.py
+++ b/homeassistant/components/recorder/statistics.py
@@ -35,6 +35,7 @@ from homeassistant.util.unit_conversion import (
     BaseUnitConverter,
     DistanceConverter,
     EnergyConverter,
+    MassConverter,
     PowerConverter,
     PressureConverter,
     SpeedConverter,
@@ -126,6 +127,7 @@ QUERY_STATISTIC_META = [
 STATISTIC_UNIT_TO_UNIT_CLASS: dict[str | None, str] = {
     DistanceConverter.NORMALIZED_UNIT: DistanceConverter.UNIT_CLASS,
     EnergyConverter.NORMALIZED_UNIT: EnergyConverter.UNIT_CLASS,
+    MassConverter.NORMALIZED_UNIT: MassConverter.UNIT_CLASS,
     PowerConverter.NORMALIZED_UNIT: PowerConverter.UNIT_CLASS,
     PressureConverter.NORMALIZED_UNIT: PressureConverter.UNIT_CLASS,
     SpeedConverter.NORMALIZED_UNIT: SpeedConverter.UNIT_CLASS,
@@ -136,6 +138,7 @@ STATISTIC_UNIT_TO_UNIT_CLASS: dict[str | None, str] = {
 STATISTIC_UNIT_TO_UNIT_CONVERTER: dict[str | None, type[BaseUnitConverter]] = {
     DistanceConverter.NORMALIZED_UNIT: DistanceConverter,
     EnergyConverter.NORMALIZED_UNIT: EnergyConverter,
+    MassConverter.NORMALIZED_UNIT: MassConverter,
     PowerConverter.NORMALIZED_UNIT: PowerConverter,
     PressureConverter.NORMALIZED_UNIT: PressureConverter,
     SpeedConverter.NORMALIZED_UNIT: SpeedConverter,
diff --git a/homeassistant/components/recorder/websocket_api.py b/homeassistant/components/recorder/websocket_api.py
index 5feb51000fb..a0150702cdb 100644
--- a/homeassistant/components/recorder/websocket_api.py
+++ b/homeassistant/components/recorder/websocket_api.py
@@ -21,6 +21,7 @@ from homeassistant.util import dt as dt_util
 from homeassistant.util.unit_conversion import (
     DistanceConverter,
     EnergyConverter,
+    MassConverter,
     PowerConverter,
     PressureConverter,
     SpeedConverter,
@@ -126,6 +127,7 @@ async def ws_handle_get_statistics_during_period(
             {
                 vol.Optional("distance"): vol.In(DistanceConverter.VALID_UNITS),
                 vol.Optional("energy"): vol.In(EnergyConverter.VALID_UNITS),
+                vol.Optional("mass"): vol.In(MassConverter.VALID_UNITS),
                 vol.Optional("power"): vol.In(PowerConverter.VALID_UNITS),
                 vol.Optional("pressure"): vol.In(PressureConverter.VALID_UNITS),
                 vol.Optional("speed"): vol.In(SpeedConverter.VALID_UNITS),
@@ -335,6 +337,11 @@ async def ws_adjust_sum_statistics(
             ENERGY_WATT_HOUR,
         ):
             return True
+        if (
+            statistics_unit == MassConverter.NORMALIZED_UNIT
+            and display_unit in MassConverter.VALID_UNITS
+        ):
+            return True
         if (
             statistics_unit == VolumeConverter.NORMALIZED_UNIT
             and display_unit in VolumeConverter.VALID_UNITS
diff --git a/homeassistant/components/sensor/__init__.py b/homeassistant/components/sensor/__init__.py
index c7b8e9a4940..a7c552a2e9e 100644
--- a/homeassistant/components/sensor/__init__.py
+++ b/homeassistant/components/sensor/__init__.py
@@ -61,6 +61,7 @@ from homeassistant.util import dt as dt_util
 from homeassistant.util.unit_conversion import (
     BaseUnitConverter,
     DistanceConverter,
+    MassConverter,
     PressureConverter,
     SpeedConverter,
     TemperatureConverter,
@@ -189,6 +190,10 @@ class SensorDeviceClass(StrEnum):
     # volume (VOLUME_*)
     VOLUME = "volume"
 
+    # weight/mass (g, kg, mg, µg, oz, lb)
+    WEIGHT = "weight"
+    """Using weight instead of mass because is fits better with every day language"""
+
 
 DEVICE_CLASSES_SCHEMA: Final = vol.All(vol.Lower, vol.Coerce(SensorDeviceClass))
 
@@ -226,6 +231,7 @@ UNIT_CONVERTERS: dict[str, type[BaseUnitConverter]] = {
     SensorDeviceClass.SPEED: SpeedConverter,
     SensorDeviceClass.TEMPERATURE: TemperatureConverter,
     SensorDeviceClass.VOLUME: VolumeConverter,
+    SensorDeviceClass.WEIGHT: MassConverter,
 }
 
 UNIT_RATIOS: dict[str, dict[str, float]] = {
@@ -238,6 +244,7 @@ UNIT_RATIOS: dict[str, dict[str, float]] = {
         TEMP_KELVIN: 1.0,
     },
     SensorDeviceClass.VOLUME: VolumeConverter.UNIT_CONVERSION,
+    SensorDeviceClass.WEIGHT: MassConverter.UNIT_CONVERSION,
 }
 
 # mypy: disallow-any-generics
diff --git a/homeassistant/components/sensor/device_condition.py b/homeassistant/components/sensor/device_condition.py
index 72ef4a62c48..93ba51d2668 100644
--- a/homeassistant/components/sensor/device_condition.py
+++ b/homeassistant/components/sensor/device_condition.py
@@ -62,6 +62,7 @@ CONF_IS_VALUE = "is_value"
 CONF_IS_VOLATILE_ORGANIC_COMPOUNDS = "is_volatile_organic_compounds"
 CONF_IS_VOLTAGE = "is_voltage"
 CONF_IS_VOLUME = "is_volume"
+CONF_IS_WEIGHT = "is_weight"
 
 ENTITY_CONDITIONS = {
     SensorDeviceClass.APPARENT_POWER: [{CONF_TYPE: CONF_IS_APPARENT_POWER}],
@@ -96,6 +97,7 @@ ENTITY_CONDITIONS = {
     ],
     SensorDeviceClass.VOLTAGE: [{CONF_TYPE: CONF_IS_VOLTAGE}],
     SensorDeviceClass.VOLUME: [{CONF_TYPE: CONF_IS_VOLUME}],
+    SensorDeviceClass.WEIGHT: [{CONF_TYPE: CONF_IS_WEIGHT}],
     DEVICE_CLASS_NONE: [{CONF_TYPE: CONF_IS_VALUE}],
 }
 
diff --git a/homeassistant/components/sensor/device_trigger.py b/homeassistant/components/sensor/device_trigger.py
index a2b92186410..9e433cea31b 100644
--- a/homeassistant/components/sensor/device_trigger.py
+++ b/homeassistant/components/sensor/device_trigger.py
@@ -61,6 +61,7 @@ CONF_VALUE = "value"
 CONF_VOLATILE_ORGANIC_COMPOUNDS = "volatile_organic_compounds"
 CONF_VOLTAGE = "voltage"
 CONF_VOLUME = "volume"
+CONF_WEIGHT = "weight"
 
 ENTITY_TRIGGERS = {
     SensorDeviceClass.APPARENT_POWER: [{CONF_TYPE: CONF_APPARENT_POWER}],
@@ -95,6 +96,7 @@ ENTITY_TRIGGERS = {
     ],
     SensorDeviceClass.VOLTAGE: [{CONF_TYPE: CONF_VOLTAGE}],
     SensorDeviceClass.VOLUME: [{CONF_TYPE: CONF_VOLUME}],
+    SensorDeviceClass.WEIGHT: [{CONF_TYPE: CONF_WEIGHT}],
     DEVICE_CLASS_NONE: [{CONF_TYPE: CONF_VALUE}],
 }
 
diff --git a/homeassistant/components/sensor/recorder.py b/homeassistant/components/sensor/recorder.py
index a2f7e14a79d..5241b123185 100644
--- a/homeassistant/components/sensor/recorder.py
+++ b/homeassistant/components/sensor/recorder.py
@@ -32,6 +32,7 @@ from homeassistant.util.unit_conversion import (
     BaseUnitConverter,
     DistanceConverter,
     EnergyConverter,
+    MassConverter,
     PowerConverter,
     PressureConverter,
     SpeedConverter,
@@ -67,6 +68,7 @@ UNIT_CONVERTERS: dict[str, type[BaseUnitConverter]] = {
     SensorDeviceClass.SPEED: SpeedConverter,
     SensorDeviceClass.TEMPERATURE: TemperatureConverter,
     SensorDeviceClass.VOLUME: VolumeConverter,
+    SensorDeviceClass.WEIGHT: MassConverter,
 }
 
 # Keep track of entities for which a warning about decreasing value has been logged
diff --git a/homeassistant/components/sensor/strings.json b/homeassistant/components/sensor/strings.json
index affc1a8e3e9..3584777bb5f 100644
--- a/homeassistant/components/sensor/strings.json
+++ b/homeassistant/components/sensor/strings.json
@@ -32,7 +32,8 @@
       "is_value": "Current {entity_name} value",
       "is_volatile_organic_compounds": "Current {entity_name} volatile organic compounds concentration level",
       "is_voltage": "Current {entity_name} voltage",
-      "is_volume": "Current {entity_name} volume"
+      "is_volume": "Current {entity_name} volume",
+      "is_weight": "Current {entity_name} weight"
     },
     "trigger_type": {
       "apparent_power": "{entity_name} apparent power changes",
@@ -65,7 +66,8 @@
       "value": "{entity_name} value changes",
       "volatile_organic_compounds": "{entity_name} volatile organic compounds concentration changes",
       "voltage": "{entity_name} voltage changes",
-      "volume": "{entity_name} volume changes"
+      "volume": "{entity_name} volume changes",
+      "weight": "{entity_name} weight changes"
     }
   },
   "state": {
diff --git a/homeassistant/components/sensor/translations/en.json b/homeassistant/components/sensor/translations/en.json
index fd801bd1416..1eeb31aa15c 100644
--- a/homeassistant/components/sensor/translations/en.json
+++ b/homeassistant/components/sensor/translations/en.json
@@ -31,7 +31,8 @@
             "is_value": "Current {entity_name} value",
             "is_volatile_organic_compounds": "Current {entity_name} volatile organic compounds concentration level",
             "is_voltage": "Current {entity_name} voltage",
-            "is_volume": "Current {entity_name} volume"
+            "is_volume": "Current {entity_name} volume",
+            "is_weight": "Current {entity_name} weight"
         },
         "trigger_type": {
             "apparent_power": "{entity_name} apparent power changes",
@@ -64,7 +65,8 @@
             "value": "{entity_name} value changes",
             "volatile_organic_compounds": "{entity_name} volatile organic compounds concentration changes",
             "voltage": "{entity_name} voltage changes",
-            "volume": "{entity_name} volume changes"
+            "volume": "{entity_name} volume changes",
+            "weight": "{entity_name} weight changes"
         }
     },
     "state": {
diff --git a/homeassistant/util/unit_conversion.py b/homeassistant/util/unit_conversion.py
index 45feb083611..30bfbed5785 100644
--- a/homeassistant/util/unit_conversion.py
+++ b/homeassistant/util/unit_conversion.py
@@ -15,6 +15,12 @@ from homeassistant.const import (
     LENGTH_MILES,
     LENGTH_MILLIMETERS,
     LENGTH_YARD,
+    MASS_GRAMS,
+    MASS_KILOGRAMS,
+    MASS_MICROGRAMS,
+    MASS_MILLIGRAMS,
+    MASS_OUNCES,
+    MASS_POUNDS,
     POWER_KILO_WATT,
     POWER_WATT,
     PRESSURE_BAR,
@@ -63,6 +69,10 @@ _NAUTICAL_MILE_TO_M = 1852  # 1 nautical mile = 1852 m
 _HRS_TO_SECS = 60 * 60  # 1 hr = 3600 seconds
 _DAYS_TO_SECS = 24 * _HRS_TO_SECS  # 1 day = 24 hours = 86400 seconds
 
+# Mass conversion constants
+_POUND_TO_G = 453.59237
+_OUNCE_TO_G = _POUND_TO_G / 16
+
 # Volume conversion constants
 _L_TO_CUBIC_METER = 0.001  # 1 L = 0.001 m³
 _ML_TO_CUBIC_METER = 0.001 * _L_TO_CUBIC_METER  # 1 mL = 0.001 L
@@ -157,6 +167,29 @@ class EnergyConverter(BaseUnitConverterWithUnitConversion):
     }
 
 
+class MassConverter(BaseUnitConverterWithUnitConversion):
+    """Utility to convert mass values."""
+
+    UNIT_CLASS = "mass"
+    NORMALIZED_UNIT = MASS_GRAMS
+    UNIT_CONVERSION: dict[str, float] = {
+        MASS_MICROGRAMS: 1 * 1000 * 1000,
+        MASS_MILLIGRAMS: 1 * 1000,
+        MASS_GRAMS: 1,
+        MASS_KILOGRAMS: 1 / 1000,
+        MASS_OUNCES: 1 / _OUNCE_TO_G,
+        MASS_POUNDS: 1 / _POUND_TO_G,
+    }
+    VALID_UNITS = {
+        MASS_GRAMS,
+        MASS_KILOGRAMS,
+        MASS_MILLIGRAMS,
+        MASS_MICROGRAMS,
+        MASS_OUNCES,
+        MASS_POUNDS,
+    }
+
+
 class PowerConverter(BaseUnitConverterWithUnitConversion):
     """Utility to convert power values."""
 
diff --git a/tests/components/sensor/test_init.py b/tests/components/sensor/test_init.py
index f9b90dc5bd5..a9ea9ce0fbe 100644
--- a/tests/components/sensor/test_init.py
+++ b/tests/components/sensor/test_init.py
@@ -12,6 +12,8 @@ from homeassistant.const import (
     LENGTH_INCHES,
     LENGTH_KILOMETERS,
     LENGTH_MILES,
+    MASS_GRAMS,
+    MASS_OUNCES,
     PRESSURE_HPA,
     PRESSURE_INHG,
     PRESSURE_KPA,
@@ -578,6 +580,31 @@ async def test_custom_unit(
             100,
             SensorDeviceClass.VOLUME,
         ),
+        # Weight
+        (
+            MASS_GRAMS,
+            MASS_OUNCES,
+            MASS_OUNCES,
+            100,
+            3.5,
+            SensorDeviceClass.WEIGHT,
+        ),
+        (
+            MASS_OUNCES,
+            MASS_GRAMS,
+            MASS_GRAMS,
+            78,
+            2211,
+            SensorDeviceClass.WEIGHT,
+        ),
+        (
+            MASS_GRAMS,
+            "peer_distance",
+            MASS_GRAMS,
+            100,
+            100,
+            SensorDeviceClass.WEIGHT,
+        ),
     ],
 )
 async def test_custom_unit_change(
diff --git a/tests/components/sensor/test_recorder.py b/tests/components/sensor/test_recorder.py
index c23a7cd9089..9bddaa8af71 100644
--- a/tests/components/sensor/test_recorder.py
+++ b/tests/components/sensor/test_recorder.py
@@ -100,6 +100,8 @@ def set_time_zone():
         ("temperature", "°F", "°F", "°C", "temperature", 13.050847, -10, 30),
         ("volume", "m³", "m³", "m³", "volume", 13.050847, -10, 30),
         ("volume", "ft³", "ft³", "m³", "volume", 13.050847, -10, 30),
+        ("weight", "g", "g", "g", "mass", 13.050847, -10, 30),
+        ("weight", "oz", "oz", "g", "mass", 13.050847, -10, 30),
     ],
 )
 def test_compile_hourly_statistics(
@@ -367,6 +369,8 @@ def test_compile_hourly_statistics_unsupported(hass_recorder, caplog, attributes
         (IMPERIAL_SYSTEM, "monetary", "SEK", "SEK", "SEK", None, 1),
         (IMPERIAL_SYSTEM, "volume", "m³", "m³", "m³", "volume", 1),
         (IMPERIAL_SYSTEM, "volume", "ft³", "ft³", "m³", "volume", 1),
+        (IMPERIAL_SYSTEM, "weight", "g", "g", "g", "mass", 1),
+        (IMPERIAL_SYSTEM, "weight", "oz", "oz", "g", "mass", 1),
         (METRIC_SYSTEM, "distance", "m", "m", "m", "distance", 1),
         (METRIC_SYSTEM, "distance", "mi", "mi", "m", "distance", 1),
         (METRIC_SYSTEM, "energy", "kWh", "kWh", "kWh", "energy", 1),
@@ -377,6 +381,8 @@ def test_compile_hourly_statistics_unsupported(hass_recorder, caplog, attributes
         (METRIC_SYSTEM, "monetary", "SEK", "SEK", "SEK", None, 1),
         (METRIC_SYSTEM, "volume", "m³", "m³", "m³", "volume", 1),
         (METRIC_SYSTEM, "volume", "ft³", "ft³", "m³", "volume", 1),
+        (METRIC_SYSTEM, "weight", "g", "g", "g", "mass", 1),
+        (METRIC_SYSTEM, "weight", "oz", "oz", "g", "mass", 1),
     ],
 )
 async def test_compile_hourly_sum_statistics_amount(
@@ -1577,6 +1583,8 @@ def test_compile_hourly_energy_statistics_multiple(hass_recorder, caplog):
         ("temperature", "°F", 30),
         ("volume", "m³", 30),
         ("volume", "ft³", 30),
+        ("weight", "g", 30),
+        ("weight", "oz", 30),
     ],
 )
 def test_compile_hourly_statistics_unchanged(
@@ -1670,6 +1678,8 @@ def test_compile_hourly_statistics_partially_unavailable(hass_recorder, caplog):
         ("temperature", "°F", 30),
         ("volume", "m³", 30),
         ("volume", "ft³", 30),
+        ("weight", "g", 30),
+        ("weight", "oz", 30),
     ],
 )
 def test_compile_hourly_statistics_unavailable(
@@ -1765,6 +1775,10 @@ def test_compile_hourly_statistics_fails(hass_recorder, caplog):
         ("measurement", "volume", "ft³", "ft³", "m³", "volume", "mean"),
         ("total", "volume", "m³", "m³", "m³", "volume", "sum"),
         ("total", "volume", "ft³", "ft³", "m³", "volume", "sum"),
+        ("measurement", "weight", "g", "g", "g", "mass", "mean"),
+        ("measurement", "weight", "oz", "oz", "g", "mass", "mean"),
+        ("total", "weight", "g", "g", "g", "mass", "sum"),
+        ("total", "weight", "oz", "oz", "g", "mass", "sum"),
     ],
 )
 def test_list_statistic_ids(
diff --git a/tests/util/test_unit_conversion.py b/tests/util/test_unit_conversion.py
index a1835c87f85..5e24c51f6b9 100644
--- a/tests/util/test_unit_conversion.py
+++ b/tests/util/test_unit_conversion.py
@@ -13,6 +13,12 @@ from homeassistant.const import (
     LENGTH_MILES,
     LENGTH_MILLIMETERS,
     LENGTH_YARD,
+    MASS_GRAMS,
+    MASS_KILOGRAMS,
+    MASS_MICROGRAMS,
+    MASS_MILLIGRAMS,
+    MASS_OUNCES,
+    MASS_POUNDS,
     POWER_KILO_WATT,
     POWER_WATT,
     PRESSURE_CBAR,
@@ -46,6 +52,7 @@ from homeassistant.util.unit_conversion import (
     BaseUnitConverter,
     DistanceConverter,
     EnergyConverter,
+    MassConverter,
     PowerConverter,
     PressureConverter,
     SpeedConverter,
@@ -70,6 +77,12 @@ INVALID_SYMBOL = "bob"
         (EnergyConverter, ENERGY_WATT_HOUR),
         (EnergyConverter, ENERGY_KILO_WATT_HOUR),
         (EnergyConverter, ENERGY_MEGA_WATT_HOUR),
+        (MassConverter, MASS_GRAMS),
+        (MassConverter, MASS_KILOGRAMS),
+        (MassConverter, MASS_MICROGRAMS),
+        (MassConverter, MASS_MILLIGRAMS),
+        (MassConverter, MASS_OUNCES),
+        (MassConverter, MASS_POUNDS),
         (PowerConverter, POWER_WATT),
         (PowerConverter, POWER_KILO_WATT),
         (PressureConverter, PRESSURE_PA),
@@ -107,6 +120,7 @@ def test_convert_same_unit(converter: type[BaseUnitConverter], valid_unit: str)
     [
         (DistanceConverter, LENGTH_KILOMETERS),
         (EnergyConverter, ENERGY_KILO_WATT_HOUR),
+        (MassConverter, MASS_GRAMS),
         (PowerConverter, POWER_WATT),
         (PressureConverter, PRESSURE_PA),
         (SpeedConverter, SPEED_KILOMETERS_PER_HOUR),
@@ -132,6 +146,7 @@ def test_convert_invalid_unit(
     [
         (DistanceConverter, LENGTH_KILOMETERS, LENGTH_METERS),
         (EnergyConverter, ENERGY_WATT_HOUR, ENERGY_KILO_WATT_HOUR),
+        (MassConverter, MASS_GRAMS, MASS_KILOGRAMS),
         (PowerConverter, POWER_WATT, POWER_KILO_WATT),
         (PressureConverter, PRESSURE_HPA, PRESSURE_INHG),
         (SpeedConverter, SPEED_KILOMETERS_PER_HOUR, SPEED_MILES_PER_HOUR),
@@ -239,6 +254,51 @@ def test_energy_convert(
     assert EnergyConverter.convert(value, from_unit, to_unit) == expected
 
 
+@pytest.mark.parametrize(
+    "value,from_unit,expected,to_unit",
+    [
+        (10, MASS_KILOGRAMS, 10000, MASS_GRAMS),
+        (10, MASS_KILOGRAMS, 10000000, MASS_MILLIGRAMS),
+        (10, MASS_KILOGRAMS, 10000000000, MASS_MICROGRAMS),
+        (10, MASS_KILOGRAMS, pytest.approx(352.73961), MASS_OUNCES),
+        (10, MASS_KILOGRAMS, pytest.approx(22.046226), MASS_POUNDS),
+        (10, MASS_GRAMS, 0.01, MASS_KILOGRAMS),
+        (10, MASS_GRAMS, 10000, MASS_MILLIGRAMS),
+        (10, MASS_GRAMS, 10000000, MASS_MICROGRAMS),
+        (10, MASS_GRAMS, pytest.approx(0.35273961), MASS_OUNCES),
+        (10, MASS_GRAMS, pytest.approx(0.022046226), MASS_POUNDS),
+        (10, MASS_MILLIGRAMS, 0.00001, MASS_KILOGRAMS),
+        (10, MASS_MILLIGRAMS, 0.01, MASS_GRAMS),
+        (10, MASS_MILLIGRAMS, 10000, MASS_MICROGRAMS),
+        (10, MASS_MILLIGRAMS, pytest.approx(0.00035273961), MASS_OUNCES),
+        (10, MASS_MILLIGRAMS, pytest.approx(0.000022046226), MASS_POUNDS),
+        (10000, MASS_MICROGRAMS, 0.00001, MASS_KILOGRAMS),
+        (10000, MASS_MICROGRAMS, 0.01, MASS_GRAMS),
+        (10000, MASS_MICROGRAMS, 10, MASS_MILLIGRAMS),
+        (10000, MASS_MICROGRAMS, pytest.approx(0.00035273961), MASS_OUNCES),
+        (10000, MASS_MICROGRAMS, pytest.approx(0.000022046226), MASS_POUNDS),
+        (1, MASS_POUNDS, 0.45359237, MASS_KILOGRAMS),
+        (1, MASS_POUNDS, 453.59237, MASS_GRAMS),
+        (1, MASS_POUNDS, 453592.37, MASS_MILLIGRAMS),
+        (1, MASS_POUNDS, 453592370, MASS_MICROGRAMS),
+        (1, MASS_POUNDS, 16, MASS_OUNCES),
+        (16, MASS_OUNCES, 0.45359237, MASS_KILOGRAMS),
+        (16, MASS_OUNCES, 453.59237, MASS_GRAMS),
+        (16, MASS_OUNCES, 453592.37, MASS_MILLIGRAMS),
+        (16, MASS_OUNCES, 453592370, MASS_MICROGRAMS),
+        (16, MASS_OUNCES, 1, MASS_POUNDS),
+    ],
+)
+def test_mass_convert(
+    value: float,
+    from_unit: str,
+    expected: float,
+    to_unit: str,
+) -> None:
+    """Test conversion to other units."""
+    assert MassConverter.convert(value, from_unit, to_unit) == expected
+
+
 @pytest.mark.parametrize(
     "value,from_unit,expected,to_unit",
     [
-- 
GitLab