Source code for toonlib.helpers

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# File: toonlib.py
"""All helper objects will live here"""

import logging
import copy
from collections import namedtuple

__author__ = '''Costas Tyfoxylos <costas.tyf@gmail.com>'''
__docformat__ = 'plaintext'
__date__ = '''13-03-2017'''

LOGGER_BASENAME = '''helpers'''
LOGGER = logging.getLogger(LOGGER_BASENAME)
LOGGER.addHandler(logging.NullHandler())


ThermostatState = namedtuple('ThermostatState', ('name',
                                                 'id',
                                                 'temperature',
                                                 'dhw'))

ThermostatInfo = namedtuple('ThermostatInfo', ('active_state',
                                               'boiler_connected',
                                               'burner_info',
                                               'current_displayed_temperature',
                                               'current_modulation_level',
                                               'current_set_point',
                                               'current_temperature',
                                               'error_found',
                                               'have_ot_boiler',
                                               'next_program',
                                               'next_set_point',
                                               'next_state',
                                               'next_time',
                                               'ot_communication_error',
                                               'program_state',
                                               'random_configuration_id',
                                               'real_set_point'))

Usage = namedtuple('Usage', ('average_daily',
                             'average',
                             'daily_cost',
                             'daily_usage',
                             'is_smart',
                             'meter_reading',
                             'value'))

Low = namedtuple('Low', ('meter_reading_low', 'daily_usage_low'))

Solar = namedtuple('Solar', ('maximum',
                             'produced',
                             'solar',
                             'average_produced',
                             'meter_reading_low_produced',
                             'meter_reading_produced',
                             'daily_cost_produced'))

PowerUsage = namedtuple('PowerUsage',
                        Usage._fields + Low._fields + Solar._fields)

Agreement = namedtuple('Agreement', ('id',
                                     'checksum',
                                     'city',
                                     'display_common_name',
                                     'display_hardware_version',
                                     'display_software_version',
                                     'heating_type',
                                     'house_number',
                                     'boiler_management',
                                     'solar',
                                     'toonly',
                                     'post_code',
                                     'street_name'))

PersonalDetails = namedtuple('PersonalDetails', ('number',
                                                 'email',
                                                 'first_name',
                                                 'last_name',
                                                 'middle_name',
                                                 'mobile_number',
                                                 'phone_number'))

Client = namedtuple('Client', ('id',
                               'checksum',
                               'hash',
                               'sample',
                               'personal_details'))


[docs]class Data(object): """Data object exposing flow and graph attributes."""
[docs] class Flow(object): """The object that exposes the flow information of categories in toon The information is rrd metrics and the object dynamically handles the accessing of attributes matching with the corresponding api endpoint if they are know, raises an exception if not. """ def __init__(self, toon_instance): self.toon = toon_instance self._endpoint = {'power': '/client/auth/getElecFlowData', 'gas': '/client/auth/getGasFlowData', 'solar': '/client/auth/getSolarFlowData'} def __getattr__(self, name): """Implements dynamic atributes on the Flow object""" endpoint = self._endpoint.get(name) if not endpoint: raise AttributeError(name) data = self.toon._get_data(endpoint) return data.get('graphData') if data.get('success') else None
[docs] class Graph(object): """The object that exposes the graph information of categories in toon The information is rrd metrics and the object dynamically handles the accessing of attributes matching with the corresponding api endpoint if they are know, raises an exception if not. """ def __init__(self, toon_instance): self.toon = toon_instance self._endpoint = {'power': '/client/auth/getElecGraphData', 'gas': '/client/auth/getGasGraphData', 'solar': '/client/auth/getSolarGraphData', 'district_heat': '/client/auth/getDistrictHeatGraphData'} def __getattr__(self, name): """Implements dynamic atributes on the Graph object""" endpoint = self._endpoint.get(name) if not endpoint: raise AttributeError(name) data = self.toon._get_data(endpoint) return data.get('graphData') if data.get('success') else None
def __init__(self, toon_instance): logger_name = u'{base}.{suffix}'.format(base=LOGGER_BASENAME, suffix=self.__class__.__name__) self._logger = logging.getLogger(logger_name) self.flow = self.Flow(toon_instance) self.graph = self.Graph(toon_instance)
[docs]class Switch(object): """Core object to implement the turning on, off or toggle Both hue lamps and fibaro plugs have a switch component that is shared. This implements that usage. """ def __init__(self, toon_instance, name): logger_name = u'{base}.{suffix}'.format(base=LOGGER_BASENAME, suffix=self.__class__.__name__) self._logger = logging.getLogger(logger_name) self.toon = toon_instance self._name = name @property def name(self): return self._name def _get_value(self, name, config=False): key = 'deviceConfigInfo' if config else 'deviceStatusInfo' return next((item.get(name) for item in self.toon._state.get(key).get('device') # noqa if item.get('name') == self.name), None)
[docs] def toggle(self): return self._change_state(not self.current_state)
[docs] def turn_on(self): return self._change_state(1)
@property def status(self): return 'on' if self.current_state else 'off' def _change_state(self, state): if not self.can_toggle: self._logger.warning('The item is not connected or locked, cannot ' 'change state.') return False else: data = copy.copy(self.toon._parameters) # noqa data.update({'state': int(state), 'devUuid': self.device_uuid}) response = self.toon._get_data('/client/auth/smartplug/setTarget', # noqa data) self._logger.debug('Response received {}'.format(response)) self.toon._clear_cache() # noqa return True @property def can_toggle(self): if not self.is_connected or self.is_locked: return False else: return True
[docs] def turn_off(self): return self._change_state(0)
@property def device_uuid(self): return self._get_value('devUUID') @property def is_connected(self): value = self._get_value('isConnected') return True if value else False @property def current_state(self): return self._get_value('currentState') @property def device_type(self): return self._get_value('devType', config=True) @property def in_switch_all_group(self): value = self._get_value('inSwitchAll', config=True) return True if value else False @property def in_switch_schedule(self): value = self._get_value('inSwitchSchedule', config=True) return True if value else False @property def zwave_index(self): return self._get_value('position', config=True) @property def is_locked(self): value = self._get_value('switchLocked', config=True) return True if value else False @property def zwave_uuid(self): return self._get_value('zwUuid', config=True)
[docs]class SmartPlug(Switch): """Object modeling the fibaro smart plugs the toon can interact with. It inherits from switch which is the common interface with the hue lamps to turn on, off or toggle """ def __init__(self, toon_instance, name): super(SmartPlug, self).__init__(toon_instance, name) @property def average_usage(self): return self._get_value('avgUsage') @property def current_usage(self): return self._get_value('currentUsage') @property def daily_usage(self): return self._get_value('dayUsage') @property def network_health_state(self): return self._get_value('networkHealthState') @property def usage_capable(self): value = self._get_value('usageCapable', config=True) return True if value else False @property def quantity_graph_uuid(self): return self._get_value('quantityGraphUuid', config=True) @property def flow_graph_uuid(self): return self._get_value('flowGraphUuid', config=True)
[docs]class Light(Switch): """Object modeling the hue light bulbs that toon can interact with. It inherits from switch which is the common interface with the hue lamps to turn on, off or toggle """ def __init__(self, toon_instance, name): super(Light, self).__init__(toon_instance, name) @property def rgb_color(self): return self._get_value('rgbColor')