2020-11-22 00:59:22 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
# SPDX-FileCopyrightText: 2020 Andrius Štikonas <andrius@stikonas.eu>
|
|
|
|
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
|
|
|
2020-12-20 22:58:04 +00:00
|
|
|
from datetime import datetime, timedelta
|
2020-12-06 22:53:50 +00:00
|
|
|
from types import SimpleNamespace
|
2020-11-22 00:59:22 +00:00
|
|
|
|
2020-12-27 20:30:12 +00:00
|
|
|
from async_property import async_property
|
|
|
|
|
2020-12-27 18:58:30 +00:00
|
|
|
from neohubapi.enums import Weekday
|
2020-12-20 22:58:04 +00:00
|
|
|
|
2020-12-06 22:53:50 +00:00
|
|
|
|
|
|
|
class NeoStat(SimpleNamespace):
|
2020-11-22 00:59:22 +00:00
|
|
|
"""
|
|
|
|
Class representing NeoStat theormostat
|
|
|
|
"""
|
|
|
|
|
2020-12-06 22:53:50 +00:00
|
|
|
def __init__(self, hub, thermostat):
|
|
|
|
self._data_ = thermostat
|
2020-11-22 10:23:27 +00:00
|
|
|
self._hub = hub
|
2020-11-22 00:59:22 +00:00
|
|
|
|
2020-12-20 22:58:04 +00:00
|
|
|
self.active_level = self._data_.ACTIVE_LEVEL
|
|
|
|
self.active_profile = self._data_.ACTIVE_PROFILE
|
|
|
|
self.available_modes = self._data_.AVAILABLE_MODES
|
|
|
|
self.away = self._data_.AWAY
|
|
|
|
self.cool_on = self._data_.COOL_ON
|
|
|
|
self.cool_temp = self._data_.COOL_TEMP
|
|
|
|
self.current_floor_temperature = self._data_.CURRENT_FLOOR_TEMPERATURE
|
|
|
|
self.weekday = Weekday(self._data_.DATE)
|
|
|
|
self.device_id = self._data_.DEVICE_ID
|
|
|
|
self.fan_control = self._data_.FAN_CONTROL
|
|
|
|
self.fan_speed = self._data_.FAN_SPEED
|
|
|
|
self.floor_limit = self._data_.ZONE_NAME
|
|
|
|
self.hc_mode = self._data_.HC_MODE
|
|
|
|
self.heat_mode = self._data_.HEAT_MODE
|
|
|
|
self.heat_on = self._data_.HEAT_ON
|
|
|
|
self.hold_cool = self._data_.HOLD_COOL
|
|
|
|
self.hold_off = self._data_.HOLD_OFF
|
|
|
|
self.hold_on = self._data_.HOLD_ON
|
|
|
|
self.hold_temp = self._data_.HOLD_TEMP
|
|
|
|
_hold_time = datetime.strptime(self._data_.HOLD_TIME, "%H:%M")
|
|
|
|
self.hold_time = timedelta(hours=_hold_time.hour, minutes=_hold_time.minute)
|
|
|
|
self.holiday = self._data_.HOLIDAY
|
|
|
|
self.lock = self._data_.LOCK
|
|
|
|
self.low_battery = self._data_.LOW_BATTERY
|
|
|
|
self.manual_off = self._data_.MANUAL_OFF
|
|
|
|
self.modelock = self._data_.MODELOCK
|
|
|
|
self.modulation_level = self._data_.MODULATION_LEVEL
|
|
|
|
self.name = self._data_.ZONE_NAME
|
|
|
|
self.offline = self._data_.OFFLINE
|
|
|
|
self.pin_number = int(self._data_.PIN_NUMBER)
|
|
|
|
self.preheat_active = int(self._data_.PREHEAT_ACTIVE)
|
|
|
|
self.prg_temp = self._data_.PRG_TEMP
|
|
|
|
self.prg_timer = self._data_.PRG_TIMER
|
|
|
|
self.set_temp = self._data_.SET_TEMP # target temperature
|
|
|
|
self.standby = self._data_.STANDBY
|
|
|
|
_switch_delay_left = datetime.strptime(self._data_.SWITCH_DELAY_LEFT, "%H:%M")
|
|
|
|
self.switch_delay_left = timedelta(hours=_switch_delay_left.hour, minutes=_switch_delay_left.minute)
|
|
|
|
self.temporary_set_flag = self._data_.TEMPORARY_SET_FLAG
|
|
|
|
self.temperature = self._data_.ACTUAL_TEMP
|
|
|
|
_time = datetime.strptime(self._data_.TIME, "%H:%M")
|
|
|
|
self.time = timedelta(hours=_time.hour, minutes=_time.minute)
|
|
|
|
self.timer_on = self._data_.TIMER_ON
|
|
|
|
self.window_open = self._data_.WINDOW_OPEN
|
|
|
|
self.write_count = self._data_.WRITE_COUNT
|
2020-11-22 10:23:27 +00:00
|
|
|
|
|
|
|
async def identify(self):
|
|
|
|
"""
|
|
|
|
Flashes red LED light
|
|
|
|
"""
|
|
|
|
|
2020-12-06 22:53:50 +00:00
|
|
|
message = {"IDENTIFY_DEV": self.name}
|
2020-11-22 10:23:27 +00:00
|
|
|
reply = {"result": "Device identifying"}
|
|
|
|
|
|
|
|
result = await self._hub._send(message, reply)
|
|
|
|
return result
|
2020-11-22 10:52:33 +00:00
|
|
|
|
|
|
|
async def rename(self, new_name):
|
|
|
|
"""
|
|
|
|
Renames this zone
|
|
|
|
"""
|
|
|
|
|
|
|
|
message = {"ZONE_TITLE": [self.name, new_name]}
|
2020-12-07 00:54:29 +00:00
|
|
|
reply = {"result": "zone renamed"}
|
2020-11-22 10:52:33 +00:00
|
|
|
|
|
|
|
result = await self._hub._send(message, reply)
|
|
|
|
return result
|
2020-11-22 11:13:24 +00:00
|
|
|
|
|
|
|
async def remove(self):
|
|
|
|
"""
|
|
|
|
Removes this zone
|
|
|
|
|
|
|
|
If successful, thermostat will be disconnected from the hub
|
|
|
|
Note that it takes a few seconds to remove thermostat
|
|
|
|
New get_zones call will still return the original list
|
|
|
|
during that period.
|
|
|
|
"""
|
|
|
|
|
|
|
|
message = {"REMOVE_ZONE": self.name}
|
|
|
|
reply = {"result": "zone removed"}
|
|
|
|
|
|
|
|
result = await self._hub._send(message, reply)
|
|
|
|
return result
|
2020-11-22 11:55:41 +00:00
|
|
|
|
2020-12-20 22:58:04 +00:00
|
|
|
async def set_lock(self, pin: int):
|
|
|
|
result = await self._hub.set_lock(pin, [self])
|
2020-11-22 11:55:41 +00:00
|
|
|
return result
|
|
|
|
|
|
|
|
async def unlock(self):
|
|
|
|
result = await self._hub.unlock([self])
|
|
|
|
return result
|
2020-11-22 12:22:14 +00:00
|
|
|
|
2020-12-20 22:58:04 +00:00
|
|
|
async def set_frost(self, state: bool):
|
2020-11-22 12:22:14 +00:00
|
|
|
result = await self._hub.frost(state, [self])
|
|
|
|
return result
|
2020-11-22 12:30:59 +00:00
|
|
|
|
|
|
|
async def set_temp(self, temperature: int):
|
|
|
|
result = await self._hub.set_temp(temperature, [self])
|
|
|
|
return result
|
2020-11-22 15:36:18 +00:00
|
|
|
|
|
|
|
async def set_diff(self, switching_differential: int):
|
|
|
|
result = await self._hub.set_diff(switching_differential, [self])
|
|
|
|
return result
|
2020-12-07 00:43:54 +00:00
|
|
|
|
2020-12-27 20:30:12 +00:00
|
|
|
@async_property
|
2020-12-07 00:43:54 +00:00
|
|
|
async def rate_of_change(self):
|
|
|
|
result = await self._hub.rate_of_change([self])
|
2020-12-27 20:30:12 +00:00
|
|
|
roc = result[self.name]
|
|
|
|
return roc
|