From 67b3552165b9ff8a709ffde952193874588d9de6 Mon Sep 17 00:00:00 2001
From: springstan <46536646+springstan@users.noreply.github.com>
Date: Mon, 9 Nov 2020 11:38:15 +0100
Subject: [PATCH] Add more units to distance conversion util (#40181)

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
---
 .../components/proximity/__init__.py          | 10 ++-
 homeassistant/util/distance.py                | 71 +++++++++++++++-
 tests/util/test_distance.py                   | 83 ++++++++++++++++++-
 3 files changed, 159 insertions(+), 5 deletions(-)

diff --git a/homeassistant/components/proximity/__init__.py b/homeassistant/components/proximity/__init__.py
index 2d0d14a69c1..6df0f50b720 100644
--- a/homeassistant/components/proximity/__init__.py
+++ b/homeassistant/components/proximity/__init__.py
@@ -12,6 +12,8 @@ from homeassistant.const import (
     LENGTH_FEET,
     LENGTH_KILOMETERS,
     LENGTH_METERS,
+    LENGTH_MILES,
+    LENGTH_YARD,
 )
 import homeassistant.helpers.config_validation as cv
 from homeassistant.helpers.entity import Entity
@@ -37,7 +39,13 @@ DEFAULT_PROXIMITY_ZONE = "home"
 DEFAULT_TOLERANCE = 1
 DOMAIN = "proximity"
 
-UNITS = [LENGTH_KILOMETERS, LENGTH_METERS, "mi", LENGTH_FEET]
+UNITS = [
+    LENGTH_METERS,
+    LENGTH_KILOMETERS,
+    LENGTH_FEET,
+    LENGTH_YARD,
+    LENGTH_MILES,
+]
 
 ZONE_SCHEMA = vol.Schema(
     {
diff --git a/homeassistant/util/distance.py b/homeassistant/util/distance.py
index 3ae809b2a9f..3bb3c258516 100644
--- a/homeassistant/util/distance.py
+++ b/homeassistant/util/distance.py
@@ -3,14 +3,27 @@ from numbers import Number
 
 from homeassistant.const import (
     LENGTH,
+    LENGTH_CENTIMETERS,
     LENGTH_FEET,
+    LENGTH_INCHES,
     LENGTH_KILOMETERS,
     LENGTH_METERS,
     LENGTH_MILES,
+    LENGTH_MILLIMETERS,
+    LENGTH_YARD,
     UNIT_NOT_RECOGNIZED_TEMPLATE,
 )
 
-VALID_UNITS = [LENGTH_KILOMETERS, LENGTH_MILES, LENGTH_FEET, LENGTH_METERS]
+VALID_UNITS = [
+    LENGTH_KILOMETERS,
+    LENGTH_MILES,
+    LENGTH_FEET,
+    LENGTH_METERS,
+    LENGTH_CENTIMETERS,
+    LENGTH_MILLIMETERS,
+    LENGTH_INCHES,
+    LENGTH_YARD,
+]
 
 
 def convert(value: float, unit_1: str, unit_2: str) -> float:
@@ -30,19 +43,35 @@ def convert(value: float, unit_1: str, unit_2: str) -> float:
 
     if unit_1 == LENGTH_MILES:
         meters = __miles_to_meters(value)
+    elif unit_1 == LENGTH_YARD:
+        meters = __yards_to_meters(value)
     elif unit_1 == LENGTH_FEET:
         meters = __feet_to_meters(value)
+    elif unit_1 == LENGTH_INCHES:
+        meters = __inches_to_meters(value)
     elif unit_1 == LENGTH_KILOMETERS:
         meters = __kilometers_to_meters(value)
+    elif unit_1 == LENGTH_CENTIMETERS:
+        meters = __centimeters_to_meters(value)
+    elif unit_1 == LENGTH_MILLIMETERS:
+        meters = __millimeters_to_meters(value)
 
     result = meters
 
     if unit_2 == LENGTH_MILES:
         result = __meters_to_miles(meters)
+    elif unit_2 == LENGTH_YARD:
+        result = __meters_to_yards(meters)
     elif unit_2 == LENGTH_FEET:
         result = __meters_to_feet(meters)
+    elif unit_2 == LENGTH_INCHES:
+        result = __meters_to_inches(meters)
     elif unit_2 == LENGTH_KILOMETERS:
         result = __meters_to_kilometers(meters)
+    elif unit_2 == LENGTH_CENTIMETERS:
+        result = __meters_to_centimeters(meters)
+    elif unit_2 == LENGTH_MILLIMETERS:
+        result = __meters_to_millimeters(meters)
 
     return result
 
@@ -52,26 +81,66 @@ def __miles_to_meters(miles: float) -> float:
     return miles * 1609.344
 
 
+def __yards_to_meters(yards: float) -> float:
+    """Convert yards to meters."""
+    return yards * 0.9144
+
+
 def __feet_to_meters(feet: float) -> float:
     """Convert feet to meters."""
     return feet * 0.3048
 
 
+def __inches_to_meters(inches: float) -> float:
+    """Convert inches to meters."""
+    return inches * 0.0254
+
+
 def __kilometers_to_meters(kilometers: float) -> float:
     """Convert kilometers to meters."""
     return kilometers * 1000
 
 
+def __centimeters_to_meters(centimeters: float) -> float:
+    """Convert centimeters to meters."""
+    return centimeters * 0.01
+
+
+def __millimeters_to_meters(millimeters: float) -> float:
+    """Convert millimeters to meters."""
+    return millimeters * 0.001
+
+
 def __meters_to_miles(meters: float) -> float:
     """Convert meters to miles."""
     return meters * 0.000621371
 
 
+def __meters_to_yards(meters: float) -> float:
+    """Convert meters to yards."""
+    return meters * 1.09361
+
+
 def __meters_to_feet(meters: float) -> float:
     """Convert meters to feet."""
     return meters * 3.28084
 
 
+def __meters_to_inches(meters: float) -> float:
+    """Convert meters to inches."""
+    return meters * 39.3701
+
+
 def __meters_to_kilometers(meters: float) -> float:
     """Convert meters to kilometers."""
     return meters * 0.001
+
+
+def __meters_to_centimeters(meters: float) -> float:
+    """Convert meters to centimeters."""
+    return meters * 100
+
+
+def __meters_to_millimeters(meters: float) -> float:
+    """Convert meters to millimeters."""
+    return meters * 1000
diff --git a/tests/util/test_distance.py b/tests/util/test_distance.py
index ee6b79c0861..e1cf7ae0f6a 100644
--- a/tests/util/test_distance.py
+++ b/tests/util/test_distance.py
@@ -3,10 +3,14 @@
 import pytest
 
 from homeassistant.const import (
+    LENGTH_CENTIMETERS,
     LENGTH_FEET,
+    LENGTH_INCHES,
     LENGTH_KILOMETERS,
     LENGTH_METERS,
     LENGTH_MILES,
+    LENGTH_MILLIMETERS,
+    LENGTH_YARD,
 )
 import homeassistant.util.distance as distance_util
 
@@ -18,8 +22,12 @@ def test_convert_same_unit():
     """Test conversion from any unit to same unit."""
     assert distance_util.convert(5, LENGTH_KILOMETERS, LENGTH_KILOMETERS) == 5
     assert distance_util.convert(2, LENGTH_METERS, LENGTH_METERS) == 2
+    assert distance_util.convert(6, LENGTH_CENTIMETERS, LENGTH_CENTIMETERS) == 6
+    assert distance_util.convert(3, LENGTH_MILLIMETERS, LENGTH_MILLIMETERS) == 3
     assert distance_util.convert(10, LENGTH_MILES, LENGTH_MILES) == 10
-    assert distance_util.convert(9, LENGTH_FEET, LENGTH_FEET) == 9
+    assert distance_util.convert(9, LENGTH_YARD, LENGTH_YARD) == 9
+    assert distance_util.convert(8, LENGTH_FEET, LENGTH_FEET) == 8
+    assert distance_util.convert(7, LENGTH_INCHES, LENGTH_INCHES) == 7
 
 
 def test_convert_invalid_unit():
@@ -42,7 +50,26 @@ def test_convert_from_miles():
     miles = 5
     assert distance_util.convert(miles, LENGTH_MILES, LENGTH_KILOMETERS) == 8.04672
     assert distance_util.convert(miles, LENGTH_MILES, LENGTH_METERS) == 8046.72
+    assert distance_util.convert(miles, LENGTH_MILES, LENGTH_CENTIMETERS) == 804672.0
+    assert distance_util.convert(miles, LENGTH_MILES, LENGTH_MILLIMETERS) == 8046720.0
+    assert distance_util.convert(miles, LENGTH_MILES, LENGTH_YARD) == 8799.9734592
     assert distance_util.convert(miles, LENGTH_MILES, LENGTH_FEET) == 26400.0008448
+    assert distance_util.convert(miles, LENGTH_MILES, LENGTH_INCHES) == 316800.171072
+
+
+def test_convert_from_yards():
+    """Test conversion from yards to other units."""
+    yards = 5
+    assert (
+        distance_util.convert(yards, LENGTH_YARD, LENGTH_KILOMETERS)
+        == 0.0045720000000000005
+    )
+    assert distance_util.convert(yards, LENGTH_YARD, LENGTH_METERS) == 4.572
+    assert distance_util.convert(yards, LENGTH_YARD, LENGTH_CENTIMETERS) == 457.2
+    assert distance_util.convert(yards, LENGTH_YARD, LENGTH_MILLIMETERS) == 4572.0
+    assert distance_util.convert(yards, LENGTH_YARD, LENGTH_MILES) == 0.002840908212
+    assert distance_util.convert(yards, LENGTH_YARD, LENGTH_FEET) == 15.00000048
+    assert distance_util.convert(yards, LENGTH_YARD, LENGTH_INCHES) == 180.0000972
 
 
 def test_convert_from_feet():
@@ -50,20 +77,70 @@ def test_convert_from_feet():
     feet = 5000
     assert distance_util.convert(feet, LENGTH_FEET, LENGTH_KILOMETERS) == 1.524
     assert distance_util.convert(feet, LENGTH_FEET, LENGTH_METERS) == 1524
+    assert distance_util.convert(feet, LENGTH_FEET, LENGTH_CENTIMETERS) == 152400.0
+    assert distance_util.convert(feet, LENGTH_FEET, LENGTH_MILLIMETERS) == 1524000.0
     assert distance_util.convert(feet, LENGTH_FEET, LENGTH_MILES) == 0.9469694040000001
+    assert distance_util.convert(feet, LENGTH_FEET, LENGTH_YARD) == 1666.66164
+    assert distance_util.convert(feet, LENGTH_FEET, LENGTH_INCHES) == 60000.032400000004
+
+
+def test_convert_from_inches():
+    """Test conversion from inches to other units."""
+    inches = 5000
+    assert distance_util.convert(inches, LENGTH_INCHES, LENGTH_KILOMETERS) == 0.127
+    assert distance_util.convert(inches, LENGTH_INCHES, LENGTH_METERS) == 127.0
+    assert distance_util.convert(inches, LENGTH_INCHES, LENGTH_CENTIMETERS) == 12700.0
+    assert distance_util.convert(inches, LENGTH_INCHES, LENGTH_MILLIMETERS) == 127000.0
+    assert distance_util.convert(inches, LENGTH_INCHES, LENGTH_MILES) == 0.078914117
+    assert (
+        distance_util.convert(inches, LENGTH_INCHES, LENGTH_YARD) == 138.88846999999998
+    )
+    assert distance_util.convert(inches, LENGTH_INCHES, LENGTH_FEET) == 416.66668
 
 
 def test_convert_from_kilometers():
     """Test conversion from kilometers to other units."""
     km = 5
-    assert distance_util.convert(km, LENGTH_KILOMETERS, LENGTH_FEET) == 16404.2
     assert distance_util.convert(km, LENGTH_KILOMETERS, LENGTH_METERS) == 5000
+    assert distance_util.convert(km, LENGTH_KILOMETERS, LENGTH_CENTIMETERS) == 500000
+    assert distance_util.convert(km, LENGTH_KILOMETERS, LENGTH_MILLIMETERS) == 5000000
     assert distance_util.convert(km, LENGTH_KILOMETERS, LENGTH_MILES) == 3.106855
+    assert distance_util.convert(km, LENGTH_KILOMETERS, LENGTH_YARD) == 5468.05
+    assert distance_util.convert(km, LENGTH_KILOMETERS, LENGTH_FEET) == 16404.2
+    assert distance_util.convert(km, LENGTH_KILOMETERS, LENGTH_INCHES) == 196850.5
 
 
 def test_convert_from_meters():
     """Test conversion from meters to other units."""
     m = 5000
-    assert distance_util.convert(m, LENGTH_METERS, LENGTH_FEET) == 16404.2
     assert distance_util.convert(m, LENGTH_METERS, LENGTH_KILOMETERS) == 5
+    assert distance_util.convert(m, LENGTH_METERS, LENGTH_CENTIMETERS) == 500000
+    assert distance_util.convert(m, LENGTH_METERS, LENGTH_MILLIMETERS) == 5000000
     assert distance_util.convert(m, LENGTH_METERS, LENGTH_MILES) == 3.106855
+    assert distance_util.convert(m, LENGTH_METERS, LENGTH_YARD) == 5468.05
+    assert distance_util.convert(m, LENGTH_METERS, LENGTH_FEET) == 16404.2
+    assert distance_util.convert(m, LENGTH_METERS, LENGTH_INCHES) == 196850.5
+
+
+def test_convert_from_centimeters():
+    """Test conversion from centimeters to other units."""
+    cm = 500000
+    assert distance_util.convert(cm, LENGTH_CENTIMETERS, LENGTH_KILOMETERS) == 5
+    assert distance_util.convert(cm, LENGTH_CENTIMETERS, LENGTH_METERS) == 5000
+    assert distance_util.convert(cm, LENGTH_CENTIMETERS, LENGTH_MILLIMETERS) == 5000000
+    assert distance_util.convert(cm, LENGTH_CENTIMETERS, LENGTH_MILES) == 3.106855
+    assert distance_util.convert(cm, LENGTH_CENTIMETERS, LENGTH_YARD) == 5468.05
+    assert distance_util.convert(cm, LENGTH_CENTIMETERS, LENGTH_FEET) == 16404.2
+    assert distance_util.convert(cm, LENGTH_CENTIMETERS, LENGTH_INCHES) == 196850.5
+
+
+def test_convert_from_millimeters():
+    """Test conversion from millimeters to other units."""
+    mm = 5000000
+    assert distance_util.convert(mm, LENGTH_MILLIMETERS, LENGTH_KILOMETERS) == 5
+    assert distance_util.convert(mm, LENGTH_MILLIMETERS, LENGTH_METERS) == 5000
+    assert distance_util.convert(mm, LENGTH_MILLIMETERS, LENGTH_CENTIMETERS) == 500000
+    assert distance_util.convert(mm, LENGTH_MILLIMETERS, LENGTH_MILES) == 3.106855
+    assert distance_util.convert(mm, LENGTH_MILLIMETERS, LENGTH_YARD) == 5468.05
+    assert distance_util.convert(mm, LENGTH_MILLIMETERS, LENGTH_FEET) == 16404.2
+    assert distance_util.convert(mm, LENGTH_MILLIMETERS, LENGTH_INCHES) == 196850.5
-- 
GitLab