# pylint: disable=no-value-for-parameter
import logging
from aiohap import Accessory, Category, characteristics, services
from caspia.meadow.services import ThermostatState
from .base import Link
logger = logging.getLogger(__name__)
[docs]class ThermostatAccessory(Accessory):
category = Category.THERMOSTAT
info = services.AccessoryInformation
thermostat = services.Thermostat
[docs]class ThermostatLink(Link):
meadow_service_type = 'thermostat'
def _create_link(self):
super()._create_link()
self._md_service = self._md_service # type: service.ThermostatBase
self._hk_accessory = ThermostatAccessory(self._md_service.name)
self._fill_accessory_info(self._hk_accessory)
self._hk_accessory.thermostat.set(
current_state=characteristics.CurrentHeatingCoolingState.State.HEAT,
target_state=characteristics.TargetHeatingCoolingState.State.HEAT,
current_temperature=None,
target_temperature=22.0,
temperature_units=characteristics.TemperatureDisplayUnits.Units.CELSIUS)
self.bridge.accessory_server.add_accessory(self._hk_accessory)
def _meadow_state_to_homekit(self, state: ThermostatState):
if state == ThermostatState.HEATING.value:
return characteristics.CurrentHeatingCoolingState.State.HEAT
elif state == ThermostatState.COOLING.value:
return characteristics.CurrentHeatingCoolingState.State.COOL
else:
return characteristics.CurrentHeatingCoolingState.State.OFF
def _homekit_state_to_meadow(self, state: characteristics.TargetHeatingCoolingState.State):
if state == characteristics.TargetHeatingCoolingState.State.HEAT:
return ThermostatState.HEATING
else:
return ThermostatState.OFF
async def _setup(self):
self._md_service.target_temp.subscribe(self._handle_meadow_target_temp_notification)
self._md_service.current_temp.subscribe(self._handle_meadow_current_temp_notification)
self._md_service.current_state.subscribe(self._handle_meadow_current_state_notification)
self._md_service.target_state.subscribe(self._handle_meadow_target_state_notification)
self._hk_accessory.thermostat.target_temperature.handle_write(
self._handle_homekit_target_temp_write)
self._hk_accessory.thermostat.target_state.handle_write(
self._handle_homekit_target_state_write)
async def _reload_state(self):
await self._md_service.enable_notifications()
await self._handle_meadow_current_state_notification(await
self._md_service.current_state.read())
await self._handle_meadow_current_temp_notification(await
self._md_service.current_temp.read())
await self._handle_meadow_target_temp_notification(await
self._md_service.target_temp.read())
await self._handle_meadow_target_state_notification(await
self._md_service.target_state.read())
async def _handle_homekit_target_temp_write(self, value, **kwargs):
await self._md_service.target_temp.write(float(value))
self._hk_accessory.thermostat.target_temperature.value = value
async def _handle_homekit_target_state_write(self, value, **kwargs):
md_state = self._homekit_state_to_meadow(value)
await self._md_service.target_state.write(md_state.value)
hk_state = self._meadow_state_to_homekit(md_state.value)
self._hk_accessory.thermostat.target_state.value = hk_state
async def _handle_meadow_target_temp_notification(self, value, **kwargs):
value = max(characteristics.TargetTemperature.min_value, value)
value = min(characteristics.TargetTemperature.max_value, value)
self._hk_accessory.thermostat.target_temperature.value = value
async def _handle_meadow_current_temp_notification(self, value, **kwargs):
value = max(characteristics.CurrentTemperature.min_value, value)
value = min(characteristics.CurrentTemperature.max_value, value)
self._hk_accessory.thermostat.current_temperature.value = float(round(value, 2))
async def _handle_meadow_current_state_notification(self, value, **kwargs):
homekit_state = self._meadow_state_to_homekit(value)
self._hk_accessory.thermostat.current_state.value = homekit_state
async def _handle_meadow_target_state_notification(self, value, **kwargs):
homekit_state = self._meadow_state_to_homekit(value)
self._hk_accessory.thermostat.target_state.value = homekit_state