Skip to content
This repository has been archived by the owner on Feb 6, 2024. It is now read-only.

Commit

Permalink
Use Decimal quantize to round half up
Browse files Browse the repository at this point in the history
- Switch the rounding method.

- Add unit tests for the rounding.
  • Loading branch information
vilppuvuorinen committed Dec 13, 2021
1 parent 1817a4e commit e5159b1
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 24 deletions.
11 changes: 5 additions & 6 deletions pymelcloud/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import asyncio
from abc import ABC, abstractmethod
from datetime import datetime, timedelta, timezone
from decimal import Decimal, ROUND_HALF_UP
from typing import Any, Dict, List, Optional

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

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

@abstractmethod
def apply_write(self, state: Dict[str, Any], key: str, value: Any):
Expand Down
20 changes: 2 additions & 18 deletions tests/test_atw_properties.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
"""Ecodan tests."""
import json
import os

import pytest
from asynctest import CoroutineMock, Mock, patch
from pymelcloud import DEVICE_TYPE_ATW
from pymelcloud.atw_device import (
OPERATION_MODE_AUTO,
Expand All @@ -21,23 +17,11 @@
ZONE_STATUS_UNKNOWN,
AtwDevice,
)
from .util import build_device


def _build_device(device_conf_name: str, device_state_name: str) -> AtwDevice:
test_dir = os.path.join(os.path.dirname(__file__), "samples")
with open(os.path.join(test_dir, device_conf_name), "r") as json_file:
device_conf = json.load(json_file)

with open(os.path.join(test_dir, device_state_name), "r") as json_file:
device_state = json.load(json_file)

with patch("pymelcloud.client.Client") as _client:
_client.update_confs = CoroutineMock()
_client.device_confs.__iter__ = Mock(return_value=[device_conf].__iter__())
_client.fetch_device_units = CoroutineMock(return_value=[])
_client.fetch_device_state = CoroutineMock(return_value=device_state)
client = _client

device_conf, client = build_device(device_conf_name, device_state_name)
return AtwDevice(device_conf, client)


Expand Down
41 changes: 41 additions & 0 deletions tests/test_device.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""Device tests."""

import pytest
from pymelcloud.ata_device import AtaDevice
from .util import build_device


def _build_device(device_conf_name: str, device_state_name: str) -> AtaDevice:
device_conf, client = build_device(device_conf_name, device_state_name)
return AtaDevice(device_conf, client)


@pytest.mark.asyncio
async def test_round_temperature():
device = _build_device("ata_listdevice.json", "ata_get.json")
device._device_conf.get("Device")["TemperatureIncrement"] = 0.5

assert device.round_temperature(23.99999) == 24.0
assert device.round_temperature(24.0) == 24.0
assert device.round_temperature(24.00001) == 24.0
assert device.round_temperature(24.24999) == 24.0
assert device.round_temperature(24.25) == 24.5
assert device.round_temperature(24.25001) == 24.5
assert device.round_temperature(24.5) == 24.5
assert device.round_temperature(24.74999) == 24.5
assert device.round_temperature(24.75) == 25.0
assert device.round_temperature(24.75001) == 25.0

device._device_conf.get("Device")["TemperatureIncrement"] = 1

assert device.round_temperature(23.99999) == 24.0
assert device.round_temperature(24.0) == 24.0
assert device.round_temperature(24.00001) == 24.0
assert device.round_temperature(24.49999) == 24.0
assert device.round_temperature(24.5) == 25.0
assert device.round_temperature(24.50001) == 25.0
assert device.round_temperature(25.0) == 25.0
assert device.round_temperature(25.00001) == 25.0
assert device.round_temperature(25.49999) == 25.0
assert device.round_temperature(25.5) == 26.0

21 changes: 21 additions & 0 deletions tests/util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import json
import os

from asynctest import CoroutineMock, Mock, patch

def build_device(device_conf_name: str, device_state_name: str):
test_dir = os.path.join(os.path.dirname(__file__), "samples")
with open(os.path.join(test_dir, device_conf_name), "r") as json_file:
device_conf = json.load(json_file)

with open(os.path.join(test_dir, device_state_name), "r") as json_file:
device_state = json.load(json_file)

with patch("pymelcloud.client.Client") as _client:
_client.update_confs = CoroutineMock()
_client.device_confs.__iter__ = Mock(return_value=[device_conf].__iter__())
_client.fetch_device_units = CoroutineMock(return_value=[])
_client.fetch_device_state = CoroutineMock(return_value=device_state)
client = _client

return device_conf, client

0 comments on commit e5159b1

Please sign in to comment.