Skip to content

Commit e9b4e8d

Browse files
authored
Fix set temperature from HA (#38)
- Allow temperature to be int - Added tests for validations - Run tests on GitHub - Bump GitHub actions - Version 1.8.1
1 parent a03d847 commit e9b4e8d

File tree

5 files changed

+83
-12
lines changed

5 files changed

+83
-12
lines changed

.github/workflows/python-publish.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ jobs:
2121
runs-on: ubuntu-latest
2222

2323
steps:
24-
- uses: actions/checkout@v3
24+
- uses: actions/checkout@v4
2525
- name: Set up Python
26-
uses: actions/setup-python@v3
26+
uses: actions/setup-python@v5
2727
with:
2828
python-version: '3.x'
2929
- name: Install dependencies

.github/workflows/python-test.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: Test Python Package
2+
3+
on:
4+
pull_request:
5+
workflow_dispatch:
6+
7+
permissions:
8+
contents: read
9+
10+
jobs:
11+
test:
12+
runs-on: ubuntu-latest
13+
strategy:
14+
matrix:
15+
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
16+
fail-fast: false
17+
steps:
18+
- uses: actions/checkout@v4
19+
- name: Set up Python
20+
uses: actions/setup-python@v5
21+
with:
22+
python-version: ${{ matrix.python-version }}
23+
- name: Run tests
24+
run: python -m unittest

pynobo.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -163,24 +163,22 @@ class API:
163163
DICT_NAME_TO_WEEK_PROFILE_STATUS = {NAME_ECO : WEEK_PROFILE_STATE_ECO, NAME_COMFORT : WEEK_PROFILE_STATE_COMFORT, NAME_AWAY : WEEK_PROFILE_STATE_AWAY, NAME_OFF : WEEK_PROFILE_STATE_OFF}
164164

165165
def is_valid_datetime(timestamp: str):
166-
try:
167-
datetime.datetime.strptime(timestamp, '%Y%m%d%H%M')
168-
except ValueError:
166+
if len(timestamp) != 12:
167+
# Leading zero is optional for some of the fields below, but we require it.
169168
return False
170-
return True
171-
172-
def is_valid_time(time_of_day: str):
173169
try:
174-
datetime.datetime.strptime(time_of_day, '%H%M')
170+
datetime.datetime.strptime(timestamp, '%Y%m%d%H%M')
175171
except ValueError:
176172
return False
177173
return True
178174

179175
def time_is_quarter(minutes: str):
180176
return int(minutes) % 15 == 0
181177

182-
def validate_temperature(temperature: str):
183-
if not temperature.isdigit():
178+
def validate_temperature(temperature: Union[int, str]):
179+
if type(temperature) not in (int, str):
180+
raise TypeError('Temperature must be integer or string')
181+
if isinstance(temperature, str) and not temperature.isdigit():
184182
raise ValueError(f'Temperature "{temperature}" must be digits')
185183
temperature_int = int(temperature)
186184
if temperature_int < 7:

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
# For a discussion on single-sourcing the version across setup.py and the
2929
# project code, see
3030
# https://packaging.python.org/en/latest/single_source_version.html
31-
version='1.8.0',
31+
version='1.8.1',
3232
description='Nobø Hub / Nobø Energy Control TCP/IP Interface',
3333

3434
license='GPLv3+',

test_pynobo.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import unittest
2+
3+
from pynobo import nobo
4+
5+
class TestValidation(unittest.TestCase):
6+
7+
def test_is_valid_datetime(self):
8+
self.assertTrue(nobo.API.is_valid_datetime("202404041800"))
9+
self.assertFalse(nobo.API.is_valid_datetime("2024040418001"))
10+
self.assertFalse(nobo.API.is_valid_datetime("20240404180"))
11+
self.assertFalse(nobo.API.is_valid_datetime("invalid"))
12+
13+
def test_time_is_quarter(self):
14+
self.assertTrue(nobo.API.time_is_quarter("00"))
15+
self.assertTrue(nobo.API.time_is_quarter("15"))
16+
self.assertTrue(nobo.API.time_is_quarter("30"))
17+
self.assertTrue(nobo.API.time_is_quarter("45"))
18+
self.assertFalse(nobo.API.time_is_quarter("01"))
19+
self.assertFalse(nobo.API.time_is_quarter("59"))
20+
21+
def test_validate_temperature(self):
22+
nobo.API.validate_temperature("20")
23+
nobo.API.validate_temperature(20)
24+
nobo.API.validate_temperature(7)
25+
nobo.API.validate_temperature(30)
26+
with self.assertRaises(TypeError):
27+
nobo.API.validate_temperature(0.0)
28+
with self.assertRaisesRegex(ValueError, "must be digits"):
29+
nobo.API.validate_temperature("foo")
30+
with self.assertRaisesRegex(ValueError, "Min temperature is 7"):
31+
nobo.API.validate_temperature(6)
32+
with self.assertRaisesRegex(ValueError, "Max temperature is 30"):
33+
nobo.API.validate_temperature(31)
34+
35+
def test_validate_week_profile(self):
36+
nobo.API.validate_week_profile(['00000','12001','16000','00000','12001','16000','00000','12001','16000','00000','12001','16000','00000','12001','16000','00000','12001','16000','00000','12001','16000'])
37+
nobo.API.validate_week_profile(['00000','00000','00000','00000','00000','00000','00000'])
38+
nobo.API.validate_week_profile(['00000','00001','00002','00004','00000','00000','00000'])
39+
with self.assertRaisesRegex(ValueError, "must contain exactly 7 entries for midnight"):
40+
nobo.API.validate_week_profile(['00000','00000','00000','00000','00000','00000'])
41+
with self.assertRaisesRegex(ValueError, "must contain exactly 7 entries for midnight"):
42+
nobo.API.validate_week_profile(['00000','00000','00000','00000','00000','00000','00000','00000'])
43+
with self.assertRaisesRegex(ValueError, "invalid state"):
44+
nobo.API.validate_week_profile(['00003','00000','00000','00000','00000','00000','00000'])
45+
with self.assertRaisesRegex(ValueError, "not in whole quarters"):
46+
nobo.API.validate_week_profile(['00000','01231','00000','00000','00000','00000','00000','00000'])
47+
48+
if __name__ == '__main__':
49+
unittest.main()

0 commit comments

Comments
 (0)