Skip to content

Commit

Permalink
Manage week profiles (#34)
Browse files Browse the repository at this point in the history
* Version 1.7.0

---------

Co-authored-by: Helge Brands <[email protected]>
  • Loading branch information
oyvindwe and HelgeBrands authored Sep 26, 2023
1 parent 35007b6 commit b07910d
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 1 deletion.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ These functions send commands to the hub.
* async_send_command - Send a list of command string(s) to the hub
* async_create_override - Override hub/zones/components
* async_update_zone - Update the name, week profile, temperature or override allowing for a zone.
* async_add_week_profile - Create a week profile
* async_update_week_profile - Update a week profile
* async_remove_week_profile - Remove a week profile

### Dictionary helper functions

Expand Down
93 changes: 93 additions & 0 deletions pynobo.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,24 @@ def validate_temperature(temperature: str):
if temperature_int > 30:
raise ValueError(f'Max temperature is 30°C')

def validate_week_profile(profile):
if type(profile) != list:
raise ValueError("Week profile must be a list")
day_count=0
for i in profile:
if len(i) != 5:
raise ValueError(f"Invalid week profile entry: {i}")
time = datetime.datetime.strptime(i[0:4], "%H%M")
if not time.minute % 15 == 0:
raise ValueError(f"Week profile entry not in whole quarters: {i}")
# Last character is state (0=Eco, 1=Comfort, 2=Away, 4=Off)
if not i[4] in "0124":
raise ValueError(f"Week profile entry contains invalid state, must be 0, 1, 2, or 4: {i}")
if time.hour == 0 and time.minute == 0:
day_count+=1
if day_count != 7:
raise ValueError("Week profile must contain exactly 7 entries for midnight (starting with 0000)")


class Model:
"""
Expand Down Expand Up @@ -916,6 +934,81 @@ async def async_update_zone(self, zone_id, name=None, week_profile_id=None, temp

await self.async_send_command(command)


async def async_add_week_profile(self, name, profile=None):
"""
Add the name and profile parameter for a week.
:param name: the new zone name
:param profile: the new profile (default None)
"""

# if no profile is defined
if profile is None:
profile=['00000','12001','16000','00000','12001','16000','00000','12001','16000','00000','12001','16000','00000','12001','16000','00000','12001','16000','00000','12001','16000']
_LOGGER.debug('profile: %s', ",".join(profile))
nobo.API.validate_week_profile(profile)

# profile id is decided by the hub
week_profile_id='0'
converted_profile =','.join(profile)
name = name.replace(" ", "\u00A0")
if len(name.encode('utf-8')) > 100:
raise ValueError(f'Zone name "{name}" too long (max 100 bytes when encoded as UTF-8)')

command = [nobo.API.ADD_WEEK_PROFILE] + [week_profile_id] + [name] + [converted_profile]

await self.async_send_command(command)


async def async_update_week_profile(self, week_profile_id: str, name=None, profile=None):
"""
Update the name and profile parameter for a week.
:param week_profile_id: the week_profile_id
:param name: the new zone name (default None)
:param profile: the new profile (default None)
"""

if week_profile_id not in self.week_profiles:
raise ValueError(f"Unknown week profile {week_profile_id}")
if name is None and profile is None:
raise ValueError("Set at least name or profile to update")

if name:
name = name.replace(" ", "\u00A0")
if len(name.encode('utf-8')) > 100:
raise ValueError(f'Zone name "{name}" too long (max 100 bytes when encoded as UTF-8)')
else:
name = self.week_profiles[week_profile_id]["name"]

if profile:
nobo.API.validate_week_profile(profile)
else:
profile = self.week_profiles[week_profile_id]["profile"]

command = [nobo.API.UPDATE_WEEK_PROFILE, week_profile_id, name, ','.join(profile)]
await self.async_send_command(command)

async def async_remove_week_profile(self, week_profile_id: str):
"""
Remove the week profile.
:param week_profile_id: the week_profile_id
"""

if week_profile_id not in self.week_profiles:
raise ValueError(f"Unknown week profile {week_profile_id}")

if week_profile_id in (v['week_profile_id'] for k, v in self.zones.items()):
raise ValueError(f"Week profile {week_profile_id} in use, can not remove")

name = self.week_profiles[week_profile_id]["name"]
profile = self.week_profiles[week_profile_id]["profile"]

command = [nobo.API.REMOVE_WEEK_PROFILE, week_profile_id, name, ','.join(profile)]
await self.async_send_command(command)

def get_week_profile_status(self, week_profile_id, dt=datetime.datetime.today()):
"""
Get the status of a week profile at a certain time in the week. Monday is day 0.
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
# For a discussion on single-sourcing the version across setup.py and the
# project code, see
# https://packaging.python.org/en/latest/single_source_version.html
version='1.6.1',
version='1.7.0',
description='Nobø Hub / Nobø Energy Control TCP/IP Interface',

license='GPLv3+',
Expand Down

0 comments on commit b07910d

Please sign in to comment.