From 901b7b62782f13a301b1f973d94e2e2e1237a09d Mon Sep 17 00:00:00 2001
From: John Allen <jallen@dynoprojects.com>
Date: Wed, 17 Jan 2024 15:06:11 -0500
Subject: [PATCH] Send target temp to Shelly TRV in F when needed (#108188)

---
 homeassistant/components/shelly/climate.py | 15 ++++++++++++++
 tests/components/shelly/test_climate.py    | 23 ++++++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/homeassistant/components/shelly/climate.py b/homeassistant/components/shelly/climate.py
index 7cc0027bbaf..64129131d0a 100644
--- a/homeassistant/components/shelly/climate.py
+++ b/homeassistant/components/shelly/climate.py
@@ -316,6 +316,21 @@ class BlockSleepingClimate(
         """Set new target temperature."""
         if (current_temp := kwargs.get(ATTR_TEMPERATURE)) is None:
             return
+
+        # Shelly TRV accepts target_t in Fahrenheit or Celsius, but you must
+        # send the units that the device expects
+        if self.block is not None and self.block.channel is not None:
+            therm = self.coordinator.device.settings["thermostats"][
+                int(self.block.channel)
+            ]
+            LOGGER.debug("Themostat settings: %s", therm)
+            if therm.get("target_t", {}).get("units", "C") == "F":
+                current_temp = TemperatureConverter.convert(
+                    cast(float, current_temp),
+                    UnitOfTemperature.CELSIUS,
+                    UnitOfTemperature.FAHRENHEIT,
+                )
+
         await self.set_state_full_path(target_t_enabled=1, target_t=f"{current_temp}")
 
     async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
diff --git a/tests/components/shelly/test_climate.py b/tests/components/shelly/test_climate.py
index 980981de754..28235325af4 100644
--- a/tests/components/shelly/test_climate.py
+++ b/tests/components/shelly/test_climate.py
@@ -146,6 +146,29 @@ async def test_climate_set_temperature(
     mock_block_device.http_request.assert_called_once_with(
         "get", "thermostat/0", {"target_t_enabled": 1, "target_t": "23.0"}
     )
+    mock_block_device.http_request.reset_mock()
+
+    # Test conversion from C to F
+    monkeypatch.setattr(
+        mock_block_device,
+        "settings",
+        {
+            "thermostats": [
+                {"target_t": {"units": "F"}},
+            ]
+        },
+    )
+
+    await hass.services.async_call(
+        CLIMATE_DOMAIN,
+        SERVICE_SET_TEMPERATURE,
+        {ATTR_ENTITY_ID: ENTITY_ID, ATTR_TEMPERATURE: 20},
+        blocking=True,
+    )
+
+    mock_block_device.http_request.assert_called_once_with(
+        "get", "thermostat/0", {"target_t_enabled": 1, "target_t": "68.0"}
+    )
 
 
 async def test_climate_set_preset_mode(