예제 #1
0
    def start_controller(self):
        if len(self._Isy_Url) > 0 and len(self._Isy_User) > 0 and len(self._Isy_Pass) > 0:
            self._isy_controller = IsySystem(url=self._Isy_Url, user=self._Isy_User, password=self._Isy_Pass)

        if self._isy_controller:
            isy_lights = self.get_lights()
            for address in self._lights:
                if address not in isy_lights:
                    self._lights[address].missing = True
            for isy_light in isy_lights:
                if isy_light not in self._lights:
                    light = Light.Light()
                    light.address = isy_light
                    light.name = isy_lights[isy_light]['name']
                    light.echo_name = isy_lights[isy_light]['name']
                    self._lights[isy_light] = light
예제 #2
0
class Director(object):
    def __init__(self, **kwargs):
        # print('Director ', self.__class__.__name__)

        self.debug = kwargs.get('debug', False)
        self._config_path = kwargs.get('config_path', '.')
        self._shut_down = 0
        self._on = False

        self._secret_key = None

        self._Isy_Url = ''
        self._Isy_User = ''
        self._Isy_Pass = ''

        self.username = ''
        self.password = ''

        self.amazon_email = ''

        self._lights = {}

        self._isy_controller = None
        self._isy_lights = None

        self.token = None

    @property
    def settings(self):
        return {'IsyUrl': self._Isy_Url, 'IsyUser': self._Isy_User, 'IsyPass': self._Isy_Pass,
                'Username': self.username, 'Password': self.password, 'AmazonEmail': self.amazon_email,
                'SecretKey': self._secret_key}

    def update_settings(self, settings):
        if (settings['IsyUrl'] != self._Isy_Url or settings['IsyUser'] != self._Isy_User or
                settings['IsyPass'] != self._Isy_Pass):

            self._Isy_Url = settings['IsyUrl']
            self._Isy_User = settings['IsyUser']
            self._Isy_Pass = settings['IsyPass']
            self.start_controller()

        if (settings['Username'] != self.username or settings['Password'] != self.password or
                settings['AmazonEmail'] != self.amazon_email):
            self.username = settings['Username']
            self.password = settings['Password']
            self.amazon_email = settings['AmazonEmail']

    @property
    def settings_complete(self):
        return (len(self._Isy_Url) > 0 and len(self._Isy_User) > 0 and len(self._Isy_Pass) > 0 and
                len(self.username) > 0 and len(self.password) > 0 and len(self.amazon_email) > 0)

    @property
    def secret_key(self):
        if self._secret_key is None:
            self._secret_key = os.urandom(32)
            self.save_config()
        return self._secret_key

    @property
    def isy_controller(self):
        return self._isy_controller

    @property
    def lights(self):
        return self._lights

    def load_config(self):
        try:
            config_fp = open(os.path.join(self._config_path, 'ISYEcho.json'))
            config = json.load(config_fp)
            config_fp.close()
        except IOError:
            config = {}

        secret_key = config.get('SecretKey')

        if secret_key is not None:
            self._secret_key = base64.b64decode(secret_key)
        else:
            self._secret_key = None

        self._Isy_Url = config.get('IsyUrl', '')
        #if self._Isy_Url == '':
        #    from ISY.IsyDiscover import isy_discover
        #    result = isy_discover(timeout=30, count=1)
        #    if len(result) == 1:
        #        import urlparse
        #        self._Isy_Url = urlparse.urlparse(result.values()[0]['URLBase']).netloc

        self._Isy_User = config.get('IsyUser', '')
        self._Isy_Pass = config.get('IsyPass', '')

        self.username = config.get('Username', '')
        self.password = config.get('Password', '')

        self.amazon_email = config.get('AmazonEmail', '')

        for light_cfg in config.get('lights', {}):
            light = Light.Light(settings=light_cfg)
            self._lights[light.address] = light

    def save_config(self):
        config = self.settings.copy()
        config['SecretKey'] = base64.b64encode(self._secret_key)
        if len(self._lights) > 0:
            config['lights'] = []
            for light_address in sorted(self._lights):
                config['lights'].append(self._lights[light_address].serialize())
        config_fp = open(os.path.join(self._config_path, 'ISYEcho.json'), 'w')
        json.dump(config, config_fp, indent=4, separators=(',', ': '), sort_keys=True)
        config_fp.write('\n')
        config_fp.close()

    def update_lights(self, lights):
        for index in lights:
            light_cfg = lights[index]
            light = self._lights[light_cfg['address']]
            light.enabled = 'enabled' in light_cfg
            light.echo_name = light_cfg['echo_name']

    def start(self):
        self.load_config()
        self.start_controller()

    def start_controller(self):
        if len(self._Isy_Url) > 0 and len(self._Isy_User) > 0 and len(self._Isy_Pass) > 0:
            self._isy_controller = IsySystem(url=self._Isy_Url, user=self._Isy_User, password=self._Isy_Pass)

        if self._isy_controller:
            isy_lights = self.get_lights()
            for address in self._lights:
                if address not in isy_lights:
                    self._lights[address].missing = True
            for isy_light in isy_lights:
                if isy_light not in self._lights:
                    light = Light.Light()
                    light.address = isy_light
                    light.name = isy_lights[isy_light]['name']
                    light.echo_name = isy_lights[isy_light]['name']
                    self._lights[isy_light] = light

    def get_lights(self):
        if self._isy_lights is None:
            self._isy_lights = {}
            nodes = self._isy_controller.get_nodes()
            for node in nodes['result']:
                category, subcat, version, other = node['type'].split('.')
                if category == '1' or category == '2':
                    if node['address'] == node['pnode']:
                        if 'family' not in node:
                            node_info = {
                                'name': node['name'],
                                'type': node['type'],
                                'address': node['address'],
                                'version': version
                            }
                            node_type_info = insteon_devices.get(category + '.' + subcat)
                            if node_type_info is not None:
                                node_info['type_desc'] = node_type_info['name']
                                node_info['type_model'] = node_type_info['model']
                            else:
                                node_info['type_desc'] = 'Node type = ' + node['type']
                                node_info['type_model'] = 'Unknown model'
                            self._isy_lights[node_info['address']] = node_info
                        else:
                            logger.debug('skipping node %s, family %s', node['name'], node['family'])
                    else:
                        logger.debug('skipping node %s, sub-device', node['name'])
                else:
                    logger.debug('skipping node %s, unsupported', node['name'])
        return self._isy_lights

    def validate_access(self, token):
        if token == self.token:
            return True
        conn = httplib.HTTPSConnection('www.amazon.com')
        conn.request('GET', '/ap/user/profile?access_token=' + token)
        resp = conn.getresponse()
        logger.debug('status = %s, reason = %s', resp.status, resp.reason)
        if resp.status == 200:
            data = resp.read()
            logger.debug('data = ' + data)
            profile = json.loads(data)
            email = profile['Profile']['PrimaryEmail']
            logger.debug('email = %s', email)
            if email == self.amazon_email:
                self.token = token
                return True
        return False