Skip to content

Commit e5159b1

Browse files
author
Vilppu Vuorinen
committed
Use Decimal quantize to round half up
- Switch the rounding method. - Add unit tests for the rounding.
1 parent 1817a4e commit e5159b1

File tree

4 files changed

+69
-24
lines changed

4 files changed

+69
-24
lines changed

pymelcloud/device.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import asyncio
33
from abc import ABC, abstractmethod
44
from datetime import datetime, timedelta, timezone
5+
from decimal import Decimal, ROUND_HALF_UP
56
from typing import Any, Dict, List, Optional
67

78
from pymelcloud.client import Client
@@ -62,12 +63,10 @@ def get_state_prop(self, name: str) -> Optional[Any]:
6263

6364
def round_temperature(self, temperature: float) -> float:
6465
"""Round a temperature to the nearest temperature increment."""
65-
increment = self.temperature_increment
66-
if temperature < 0:
67-
half_increment = -increment / 2.0
68-
else:
69-
half_increment = increment / 2.0
70-
return round((temperature + half_increment) / increment) * increment
66+
return float(
67+
Decimal(str(temperature / self.temperature_increment))
68+
.quantize(Decimal('1'), rounding=ROUND_HALF_UP)
69+
) * self.temperature_increment
7170

7271
@abstractmethod
7372
def apply_write(self, state: Dict[str, Any], key: str, value: Any):

tests/test_atw_properties.py

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
"""Ecodan tests."""
2-
import json
3-
import os
4-
52
import pytest
6-
from asynctest import CoroutineMock, Mock, patch
73
from pymelcloud import DEVICE_TYPE_ATW
84
from pymelcloud.atw_device import (
95
OPERATION_MODE_AUTO,
@@ -21,23 +17,11 @@
2117
ZONE_STATUS_UNKNOWN,
2218
AtwDevice,
2319
)
20+
from .util import build_device
2421

2522

2623
def _build_device(device_conf_name: str, device_state_name: str) -> AtwDevice:
27-
test_dir = os.path.join(os.path.dirname(__file__), "samples")
28-
with open(os.path.join(test_dir, device_conf_name), "r") as json_file:
29-
device_conf = json.load(json_file)
30-
31-
with open(os.path.join(test_dir, device_state_name), "r") as json_file:
32-
device_state = json.load(json_file)
33-
34-
with patch("pymelcloud.client.Client") as _client:
35-
_client.update_confs = CoroutineMock()
36-
_client.device_confs.__iter__ = Mock(return_value=[device_conf].__iter__())
37-
_client.fetch_device_units = CoroutineMock(return_value=[])
38-
_client.fetch_device_state = CoroutineMock(return_value=device_state)
39-
client = _client
40-
24+
device_conf, client = build_device(device_conf_name, device_state_name)
4125
return AtwDevice(device_conf, client)
4226

4327

tests/test_device.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
"""Device tests."""
2+
3+
import pytest
4+
from pymelcloud.ata_device import AtaDevice
5+
from .util import build_device
6+
7+
8+
def _build_device(device_conf_name: str, device_state_name: str) -> AtaDevice:
9+
device_conf, client = build_device(device_conf_name, device_state_name)
10+
return AtaDevice(device_conf, client)
11+
12+
13+
@pytest.mark.asyncio
14+
async def test_round_temperature():
15+
device = _build_device("ata_listdevice.json", "ata_get.json")
16+
device._device_conf.get("Device")["TemperatureIncrement"] = 0.5
17+
18+
assert device.round_temperature(23.99999) == 24.0
19+
assert device.round_temperature(24.0) == 24.0
20+
assert device.round_temperature(24.00001) == 24.0
21+
assert device.round_temperature(24.24999) == 24.0
22+
assert device.round_temperature(24.25) == 24.5
23+
assert device.round_temperature(24.25001) == 24.5
24+
assert device.round_temperature(24.5) == 24.5
25+
assert device.round_temperature(24.74999) == 24.5
26+
assert device.round_temperature(24.75) == 25.0
27+
assert device.round_temperature(24.75001) == 25.0
28+
29+
device._device_conf.get("Device")["TemperatureIncrement"] = 1
30+
31+
assert device.round_temperature(23.99999) == 24.0
32+
assert device.round_temperature(24.0) == 24.0
33+
assert device.round_temperature(24.00001) == 24.0
34+
assert device.round_temperature(24.49999) == 24.0
35+
assert device.round_temperature(24.5) == 25.0
36+
assert device.round_temperature(24.50001) == 25.0
37+
assert device.round_temperature(25.0) == 25.0
38+
assert device.round_temperature(25.00001) == 25.0
39+
assert device.round_temperature(25.49999) == 25.0
40+
assert device.round_temperature(25.5) == 26.0
41+

tests/util.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import json
2+
import os
3+
4+
from asynctest import CoroutineMock, Mock, patch
5+
6+
def build_device(device_conf_name: str, device_state_name: str):
7+
test_dir = os.path.join(os.path.dirname(__file__), "samples")
8+
with open(os.path.join(test_dir, device_conf_name), "r") as json_file:
9+
device_conf = json.load(json_file)
10+
11+
with open(os.path.join(test_dir, device_state_name), "r") as json_file:
12+
device_state = json.load(json_file)
13+
14+
with patch("pymelcloud.client.Client") as _client:
15+
_client.update_confs = CoroutineMock()
16+
_client.device_confs.__iter__ = Mock(return_value=[device_conf].__iter__())
17+
_client.fetch_device_units = CoroutineMock(return_value=[])
18+
_client.fetch_device_state = CoroutineMock(return_value=device_state)
19+
client = _client
20+
21+
return device_conf, client

0 commit comments

Comments
 (0)