示例#1
0
 def set_driver(self, mdrv, val, default=0, force=False, report=True):
     #LOGGER.debug(f'{self.lpfx} {mdrv},{val} default={default} force={force},report={report}')
     if val is None:
         # Restore from DB for existing nodes
         try:
             val = self.getDriver(mdrv)
             LOGGER.info(f'{self.lpfx} {val}')
         except:
             LOGGER.warning(
                 f'{self.lpfx} getDriver({mdrv}) failed which can happen on new nodes, using {default}'
             )
     val = default if val is None else int(val)
     try:
         if not mdrv in self.__my_drivers or val != self.__my_drivers[
                 mdrv] or force:
             self.setDriver(mdrv, val, report=report)
             info = ''
             if self.id in NODE_DEF_MAP and mdrv in NODE_DEF_MAP[self.id]:
                 info += f"'{NODE_DEF_MAP[self.id][mdrv]['name']}' = "
                 info += f"'{NODE_DEF_MAP[self.id][mdrv]['keys'][val]}'" if val in NODE_DEF_MAP[
                     self.id][mdrv]['keys'] else "'NOT IN NODE_DEF_MAP'"
             self.__my_drivers[mdrv] = val
             LOGGER.debug(f'{self.lpfx} set_driver({mdrv},{val}) {info}')
         #else:
         #    LOGGER.debug(f'{self.lpfx} not necessary')
     except:
         LOGGER.error(f'{self.lpfx} set_driver({mdrv},{val}) failed')
         return None
     return val
 def set_listen(self, val):
     LOGGER.warning('Set to {}'.format(val))
     if self.isy_hue_emu is not False:
         if val == 0:
             self.isy_hue_emu.stop_listener()
         else:
             self.isy_hue_emu.start_listener()
             self.listen_cnt = HueEmuController.LISTEN_TIMEOUT
     self.setDriver('GV2', val)
 def longPoll(self):
     self.heartbeat()
     if self.initializing:
         return
     if self.get_listen() == 1:
         LOGGER.warning('Listen Count = {}'.format(self.listen_cnt))
         if self.listen_cnt > 0:
             self.listen_cnt -= 1
         else:
             self.set_listen(0)
示例#4
0
 def update_status(self):
     # Reconnect?
     if self.camect is False:
         LOGGER.warning(
             f'{self.lpfx}: reconnecting since camect={self.camect}')
         self.camect = self.controller.reconnect_host(self.host)
     if self.camect is False:
         return False
     for cam in self.list_cameras():
         if cam['id'] in self.cams_by_id:
             #LOGGER.debug(f"{self.lpfx}: Check camera: {cam}")
             self.cams_by_id[cam['id']].update_status(cam)
示例#5
0
 def check_profile(self,thermostats):
     self.profile_info = get_profile_info(LOGGER)
     #
     # First get all the climate programs so we can build the profile if necessary
     #
     climates = dict()
     for thermostatId, thermostat in thermostats.items():
         # Only get program data if we have the node.
         fullData = self.getThermostatSelection(thermostatId,includeProgram=True)
         if fullData is not False:
             programs = fullData['thermostatList'][0]['program']
             climates[thermostatId] = list()
             for climate in programs['climates']:
                 climates[thermostatId].append({'name': climate['name'], 'ref':climate['climateRef']})
     LOGGER.debug("check_profile: climates={}".format(climates))
     #
     # Set Default profile version if not Found
     #
     cdata = deepcopy(self.polyConfig['customData'])
     LOGGER.info('check_profile: profile_info={}'.format(self.profile_info))
     LOGGER.info('check_profile:   customData={}'.format(cdata))
     if not 'profile_info' in cdata:
         update_profile = True
     elif self.profile_info['version'] == cdata['profile_info']['version']:
         # Check if the climates are different
         update_profile = False
         LOGGER.info('check_profile: update_profile={} checking climates.'.format(update_profile))
         if 'climates' in cdata:
             current = cdata['climates']
             if not update_profile:
                 # Check if the climates have changed.
                 for id in climates:
                     if id in current:
                         if len(climates[id]) == len(current[id]):
                             for i in range(len(climates[id])):
                                 if climates[id][i] != current[id][i]:
                                     update_profile = True
                         else:
                             update_profile = True
                     else:
                         update_profile = True
         else:
             update_profile = True
     else:
         update_profile = True
     LOGGER.warning('check_profile: update_profile={}'.format(update_profile))
     if update_profile:
         self.write_profile(climates)
         self.poly.installprofile()
         cdata['profile_info'] = self.profile_info
         cdata['climates'] = climates
         self.saveCustomDataWait(cdata)
示例#6
0
 def _getOAuth(self):
     # Do we have it?
     sdata = self._getOAuthInit()
     LOGGER.debug("_getOAuth: sdata={}".format(sdata))
     if sdata is not False:
         LOGGER.debug('Init={}'.format(sdata))
         self.serverdata['api_key'] = sdata['api_key']
         self.serverdata['api_client'] = sdata['api_client']
     else:
         #LOGGER.error(self.poly.init)
         url = 'https://{}/authorize?response_type=code&client_id={}&redirect_uri={}&state={}'.format(ECOBEE_API_URL,self.api_key,self.redirect_url,self.poly.init['worker'])
         msg = 'No existing Authorization found, Please <a target="_blank" href="{}">Authorize access to your Ecobee Account</a>'.format(url)
         self.addNotice({'oauth': msg})
         LOGGER.warning(msg)
         self.waiting_on_tokens = "OAuth"
示例#7
0
 def get_driver(self, mdrv, default=None):
     # Restore from DB for existing nodes
     try:
         val = self.getDriver(mdrv)
         LOGGER.info(f"{self.lpfx} {mdrv}={val}")
         if val is None:
             LOGGER.info(
                 f"{self.lpfx} getDriver({mdrv}) returned None which can happen on new nodes, using {default}"
             )
             val = default
     except:
         LOGGER.warning(
             f"{self.lpfx} getDriver({mdrv}) failed which can happen on new nodes, using {default}"
         )
         val = default
     return val
示例#8
0
 def check_api(self):
     """
     Check if api being used is old and user needs to re-auth
     """
     msg = None
     if 'api_key' in self.polyConfig['customData']:
         if self.polyConfig['customData']['api_key'] != self.api_key:
             msg = 'You are using old api key "{}".'.format(self.polyConfig['customData']['api_key'])
             return False
     elif 'tokenData' in self.polyConfig['customData']:
         msg = 'No api key found, if you have previously authorized, '
     if msg is not None:
         msg += ' Please <a target="_blank" href="https://www.ecobee.com/consumerportal/">Signin to your Ecobee account</a>. Click on Profile > My Apps > Remove App of the old Nodeserver, and resart this NodeServer'
         LOGGER.warning(msg)
         self.addNotice({'check_api': msg})
         return False
     return True
示例#9
0
 def set_driver(self,mdrv,val,default=0,force=False,report=True,prec=0,uom=None):
     LOGGER.debug(f'{self.lpfx} {mdrv},{val} default={default} force={force},report={report}')
     if val is None:
         # Restore from DB for existing nodes
         try:
             val = self.getDriver(mdrv)
             LOGGER.info(f'{self.lpfx} {val}')
         except:
             LOGGER.warning(f'{self.lpfx} getDriver({mdrv}) failed which can happen on new nodes, using {default}')
     if val is None:
         val = default
     elif prec == 0:
         try:
             val = int(val)
         except Exception as err:
             LOGGER.error(f'{self.lpfx} Error converting {val} to integer, will use default={default} for {mdrv}',exc_info=True)
     else:
         try:
             val = myfloat(val,prec)
         except Exception as err:
             LOGGER.error(f'{self.lpfx} Error converting {val} to float, will use default={default} for {mdrv}',exc_info=True)
     try:
         if not mdrv in self.__my_drivers or val != self.__my_drivers[mdrv] or force:
             self.setDriver(mdrv,val,report=report,uom=uom)
             try:
                 info = ''
                 if self.id in NODE_DEF_MAP and mdrv in NODE_DEF_MAP[self.id]:
                     info += f"'{NODE_DEF_MAP[self.id][mdrv]['name']}' = "
                     if 'keys' in NODE_DEF_MAP[self.id][mdrv]:
                         info += f"'{NODE_DEF_MAP[self.id][mdrv]['keys'][val]}'" if val in NODE_DEF_MAP[self.id][mdrv]['keys'] else "'NOT IN NODE_DEF_MAP'"
                     else:
                         info += str(val)
                 self.__my_drivers[mdrv] = val
                 LOGGER.info(f'{self.lpfx} set_driver({mdrv},{val}) {info}')
             except Exception as err:
                 LOGGER.error(f'{self.lpfx} Internal error getting node driver info for {mdrv}',exc_info=True)
                 LOGGER.info(f'{self.lpfx} set_driver({mdrv},{val})')
         #else:
         #    LOGGER.debug(f'{self.lpfx} not necessary')
     except:
         LOGGER.error(f'{self.lpfx} set_driver({mdrv},{val}) failed',exc_info=True)
         return None
     return val
示例#10
0
 def ecobeeDelete(self):
     if 'access_token' in self.tokenData:
         res = self.session.delete("/oauth2/acess_tokens/"+self.tokenData['access_token'])
         if res is False:
             return False
         if 'error' in res:
             LOGGER.error('ecobeePost: error="{}" {}'.format(res['error'], res['error_description']))
             return False
         res_data = res['data']
         res_code = res['code']
         if 'status' in res_data:
             if 'code' in res_data['status']:
                 if res_data['status']['code'] == 204:
                     LOGGER.info("Revoke successful")
                     return True
                 else:
                     LOGGER.error('Bad return code {}:{}'.format(res_data['status']['code'],res_data['status']['message']))
     else:
         LOGGER.warning("No access_token to revoke...")
     return False
示例#11
0
 def _getOAuthInit(self):
     """
     See if we have the oauth data stored already
     """
     sdata = {}
     if self._cloud:
         error = False
         if 'clientId' in self.poly.init['oauth']:
             sdata['api_client'] =  self.poly.init['oauth']['clientId']
         else:
             LOGGER.warning('Unable to find Client ID in the init oauth data: {}'.format(self.poly.init['oauth']))
             error = True
         if 'clientSecret' in self.poly.init['oauth']:
             sdata['api_key'] =  self.poly.init['oauth']['clientSecret']
         else:
             LOGGER.warning('Unable to find Client Secret in the init oauth data: {}'.format(self.poly.init['oauth']))
             error = True
         if error:
             return False
     return sdata
    def start(self):
        LOGGER.info('Started LutronCaseta NodeServer')
        self.poly.add_custom_config_docs("<b>To obtain oauth code, follow <a href='{}' target='_blank'>this link</a> and copy the 'code' portion of the error page url</b>".format(AUTHORIZE_URL))
        # This grabs the server.json data and checks profile_version is up to date
        serverdata = self.poly.get_server_data(check_profile=True)
        self.setDriver('ST', 1)
        LOGGER.info('Started Lutron Caseta NodeServer {}'.format(serverdata['version']))
        if self.getDriver('GV1') is None:
            LOGGER.warning('Updating myself since there is no GV1')
            self.addNode(self,update=True)
        self.set_debug_level()
        self.mainloop = mainloop
        asyncio.set_event_loop(mainloop)
        self.hb = 0
        self.devices = dict()
        self.heartbeat()
        self.check_params()
        if not self.lutron_bridge_ip and not self.oauth_code:
            return

        # Get or generate private key
        self.private_key = self.get_priv_key()
        LOGGER.info("Private key loaded")
        # get or generate certifiate
        self.certificate = self.get_certificate()
        LOGGER.info("Certificate loaded")
        # Create an ssl socket to smartbridge
        raw_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        ssl_socket = ssl.wrap_socket(raw_socket, keyfile='./caseta.key',
                                     certfile='./caseta.crt',
                                     ssl_version=ssl.PROTOCOL_TLSv1_2)
        # User socket to get smartbridge certificate
        if self.get_bridge_cert(ssl_socket):
            LOGGER.info("Bridge certificate saved")
            self.bridge_connect()

        ssl_socket.close()
        self.discover()
示例#13
0
 def callback(self, event):
     # {'type': 'alert', 'desc': 'Out Front Door just saw a person.', 'url': 'https://home.camect.com/home/...',
     # 'cam_id': '96f69defdef1d0b6602a', 'cam_name': 'Out Front Door', 'detected_obj': ['person']}
     LOGGER.debug(f'{event}')
     try:
         if event['type'] == 'mode':
             # Can't really use this: {'type': 'mode', 'desc': 'HOME'}
             self.set_mode_by_name(event['desc'])
             self.controller.set_mode_all()
         elif 'cam_id' in event:
             # Anything with cam get's passed to the camera
             if event['cam_id'] in self.cams_by_id:
                 self.cams_by_id[event['cam_id']].callback(event)
             else:
                 LOGGER.warning(
                     f"{self.lpfx}: Event for unknown cam_id={event['cam_id']}: {event}"
                 )
         else:
             LOGGER.error(
                 f'{self.lpfx}: Unknwon event, not type=mode or cam_id: {event}'
             )
     except:
         LOGGER.error(f'{self.lpfx}: in callback: ', exc_info=True)
示例#14
0
 def l_warning(self, name, string):
     LOGGER.warning("%s:%s:%s: %s" % (self.id, self.name, name, string))
示例#15
0
    def purge(self,do_delete=False):
        LOGGER.info("%s starting do_delete=%s",self.lpfx,do_delete)
        self.removeNoticesAll()
        #LOGGER.debug("%s config=",self.lpfx,config)
        #
        # Check for removed activities or devices
        #
        # This can change while we are checking if another hub is being added...
        #LOGGER.debug("%s",self.controller.poly.config)
        # These are all the nodes from the config, not the real nodes we added...
        nodes = self.controller.poly.config['nodes'].copy()
        # Pattern match hub address s
        pch = re.compile('h([a-f0-9]+)$')
        # Pattern match activity and device addresses
        pcad = re.compile('(.)(\d+)$')
        activities = self.harmony_config['info']['activities']
        devices    = self.harmony_config['info']['devices']
        msg_pfx = "Deleting" if do_delete else "Want to delete"
        delete_cnt = 0
        # Check if we still have them.
        for node in nodes:
            address = node['address']
            if address != self.address:
                #LOGGER.info("%s Checking Node: %s",self.lpfx,node)
                LOGGER.info("%s Checking Node: %s",self.lpfx,address)
                match = pch.match(address)
                LOGGER.debug("  Match Hub: %s", match)
                if match:
                    id   = match.group(1)
                    #LOGGER.debug("Got: %s %s", type,match)
                    LOGGER.debug('%s   Check if Hub %s "%s" id=%s still exists',self.lpfx,address,node['name'],id)
                    ret = next((d for d in self.hubs if d['address'] == address), None)
                    LOGGER.debug('%s    Got: %s',self.lpfx,ret)
                    if ret is None:
                        delete_cnt += 1
                        msg = '%s Hub that is no longer found %s "%s"' % (msg_pfx,address,node['name'])
                        LOGGER.warning('%s %s',self.lpfx,msg)
                        self.addNotice(msg)
                        if do_delete:
                            self.controller.poly.delNode(address)
                else:
                    match = pcad.match(address)
                    LOGGER.debug("  Match AD: %s", match)
                    if match:
                        type = match.group(1)
                        id   = int(match.group(2))
                        LOGGER.debug(" np: %s", node['primary'])
                        if node['primary'] in self.nodes:
                            pname = self.nodes[node['primary']].name
                        else:
                            pname = node['primary']
                        #LOGGER.debug("Got: %s %s", type,match)
                        if type == 'a':
                            LOGGER.debug('%s   Check if Activity %s "%s" id=%s still exists',self.lpfx,address,node['name'],id)
                            item = next((d for d in activities if int(d['id']) == id), None)
                            LOGGER.debug('%s    Got: %s',self.lpfx,item)
                            if item is None or item['cnt'] == 0:
                                delete_cnt += 1
                                msg = '%s Activity for "%s" that is no longer used %s "%s"' % (msg_pfx,pname,address,node['name'])
                                LOGGER.warning('%s %s',self.lpfx,msg)
                                self.addNotice(msg)
                                if do_delete:
                                    self.controller.poly.delNode(address)
                        elif type == 'd':
                            LOGGER.debug('%s   Check if Device %s "%s" id=%s still exists',self.lpfx,address,node['name'],id)
                            item = next((d for d in devices if int(d['id']) == id), None)
                            LOGGER.debug('%s    Got: %s',self.lpfx,item)
                            if item is None or item['cnt'] == 0:
                                delete_cnt += 1
                                msg = '%s Device for "%s" that is no longer used %s "%s"' % (msg_pfx,pname,address,node['name'])
                                LOGGER.warning('%s %s',self.lpfx,msg)
                                self.addNotice(msg)
                                if do_delete:
                                    self.controller.poly.delNode(address)
                        else:
                            LOGGER.warning('%s Unknown type "%s" "%s" id=%s still exists',self.lpfx,type,address,node['name'])

        if delete_cnt > 0 and not do_delete:
            self.addNotice("Please run 'Purge Execute' on %s in Admin Console" % self.name)

        LOGGER.info("%s done",self.lpfx)
        self.purge_run = True
示例#16
0
    def _discover(self):
        # Clear the hubs now so we clear some that may have been improperly added.
        self.clear_hubs()
        # Set all hubs to not found
        for hub in self.hubs:
            hub['found'] = False
        #
        # Look for the hubs...
        #
        self.setDriver('GV7', 2)
        auto_discover = self.getDriver('GV8')
        discover_result = None
        if auto_discover is None:
            auto_discover = 1
        else:
            auto_discover = int(auto_discover)
        if (auto_discover == 0):
            self.l_info('discover','harmony_discover: skipping since auto discover={0}...'.format(auto_discover))
            discover_result = list()
        else:
            self.l_info('discover','harmony_discover: starting...')
            sys.path.insert(0,"pyharmony")
            from pyharmony import discovery as harmony_discovery
            harmony_discovery.logger = LOGGER
            try:
                discover_result = harmony_discovery.discover(scan_attempts=10,scan_interval=1)
            except (OSError) as err:
                self.setDriver('GV7', 9)
                self.l_error('discover','pyharmony discover failed. May need to restart this nodeserver: {}'.format(err), exc_info=True)
            self.l_info('discover','harmony_discover: {0}'.format(discover_result))
        #
        # Add the nodes
        #
        self.setDriver('GV7', 3)
        #
        # First from customParams.
        #
        for param in self.polyConfig['customParams']:
            # Look for customParam starting with hub_
            match = re.match( "hub_(.*)", param, re.I)
            self.l_info('discover','param={} match={}'.format(param,match))
            if match is not None:
                # The hub address is everything following the hub_
                address = match.group(1)
                self.l_info('discover','process param={0} address={1}'.format(param,address))
                # Get the customParam value which is json code
                #  { "name": "HarmonyHub FamilyRoom", "host": "192.168.1.86" }
                cfg = self.polyConfig['customParams'][param]
                cfgd = None
                try:
                    cfgd = json.loads(cfg)
                except:
                    err = sys.exc_info()[0]
                    self.l_error('discover','failed to parse cfg={0} Error: {1}'.format(cfg,err))
                if cfgd is not None:
                    # Check that name and host are defined.
                    addit = True
                    if not 'name' in cfgd:
                        self.l_error('discover','No name in customParam {0} value={1}'.format(param,cfg))
                        addit = False
                    if not 'host' in cfgd:
                        self.l_error('discover','No host in customParam {0} value={1}'.format(param,cfg))
                        addit = False
                    if addit:
                        hub_hash = {'address': address, 'name': get_valid_node_name(cfgd['name']), 'host': cfgd['host'], 'port': 5222, 'found': True, 'custom': True}
                        index = next((idx for (idx, hub) in enumerate(self.hubs) if hub['name'] == hub_name), None)
                        if index is None:
                            self.hubs.append(hub_hash)
                        else:
                            self.hubs[index] = hub_hash

        #
        # Next the discovered ones
        #
        tst = time.strftime("%m%d%Y-%H%M%S")
        ust = 'uuid-save-%s' % (tst)
        if discover_result is not None:
            LOGGER.debug("hubs.list=%s",self.hubs)
            for config in discover_result:
                LOGGER.debug("hub config: %s",config)
                addit = True
                if 'current_fw_version' in config:
                    if config['current_fw_version'] == '4.15.206':
                        self.l_error('discover','current_fw_version={} which is not supported.  See: {}'.
                        format(
                            config['current_fw_version'],
                            'https://community.logitech.com/s/question/0D55A00008D4bZ4SAJ/harmony-hub-firmware-update-fixes-vulnerabilities'
                        ))
                        addit = False
                else:
                    self.l_error('discover','current_fw_version not in config?  Will try to use anyway {}'.format(config))
                if addit:
                    # See if the hub is already in the list.
                    hub_address = 'h'+id_to_address(config['uuid'],13)
                    hub_name    = get_valid_node_name(config['friendlyName'])
                    index = next((idx for (idx, hub) in enumerate(self.hubs) if hub['name'] == hub_name), None)
                    LOGGER.debug('found index=%s',index)
                    if index is None:
                        # Not seen, or is a different name
                        hub_hash = {
                            'address': hub_address,
                            'name':    hub_name,
                        }
                        self.hubs.append(hub_hash)
                    else:
                        # Keep the same address for this hub name.
                        hub_hash = self.hubs[index]
                        if 'uuid' in hub_hash:
                            if hub_hash['uuid'] != config['uuid']:
                                LOGGER.warning("Seems that hub '%s' uuid changed from '%s' to '%s' will continue using old address %s",hub_name,hub_hash['uuid'],config['uuid'],hub_address)
                                hub_hash[ust] = hub_hash['uuid']
                    # These always use the latest data.
                    hub_hash['date_time'] = tst
                    hub_hash['host']      = config['ip']
                    hub_hash['port']      = config['port']
                    hub_hash['found']     = True
                    hub_hash['save']      = True
                    hub_hash['uuid']      = config['uuid']
        #
        # Write warnings about previously known Hubs
        #
        for hub in self.hubs:
            if not 'found' in hub or not hub['found']:
                LOGGER.warning("Previously known hub '%s' did not respond to discover",hub['name'])

        self.save_hubs()
        #
        # Build the profile
        # It needs the hub_list set, so we will reset it later.
        if self._build_profile():
            #
            # Now really add them.
            self.add_hubs()

        # Check on the purge
        self.purge(do_delete=False)
示例#17
0
 def delete(self):
     LOGGER.warning("Nodeserver is being deleted...")
示例#18
0
    def check_params(self):
        """
        Check all user params are available and valid
        """
        self.removeNoticesAll()
        # Assume it's good unless it's not
        self.config_st = True
        # TODO: Only when necessary
        self.update_profile()
        # Temperature Units
        default_temperature_unit = "F"
        if "temperature_unit" in self.polyConfig["customParams"]:
            self.temperature_unit = self.polyConfig["customParams"][
                "temperature_unit"]
        else:
            self.temperature_unit = default_temperature_unit
            LOGGER.error(
                f"{self.lpfx} temperature unit not defined in customParams, Using default {self.temperature_unit}"
            )
        self.temperature_uom = 4 if self.controller.temperature_unit == "C" else 17
        LOGGER.info(
            f"temperature_unit={self.temperature_unit} temerature_uom={self.temperature_uom}"
        )

        # Host
        default_host = "Your_ELK_IP_Or_Host:PortNum"
        if "host" in self.polyConfig["customParams"]:
            self.host = self.polyConfig["customParams"]["host"]
        else:
            self.host = default_host
            LOGGER.error(
                f"{self.lpfx} host not defined in customParams, please add it.  Using {self.host}"
            )
        # Code
        default_code = "Your_ELK_User_Code_for_Polyglot"
        # Fix messed up code
        if "keypad_code" in self.polyConfig["customParams"]:
            self.user_code = int(self.polyConfig["customParams"]["user_code"])
        elif "user_code" in self.polyConfig["customParams"]:
            try:
                self.user_code = int(
                    self.polyConfig["customParams"]["user_code"])
            except:
                self.user_code = default_code
                self.addNotice(
                    "ERROR user_code is not an integer, please fix, save and restart this nodeserver",
                    "host",
                )
        else:
            self.user_code = default_code
            LOGGER.error(
                f"{self.lpfx} user_code not defined in customParams, please add it.  Using {self.user_code}"
            )
        # Areas
        self.use_areas = self.getCustomParam("areas")
        self.use_areas_list = ()
        if self.use_areas == "":
            errs = "No areas defined in config so none will be added"
            LOGGER.error(errs)
            self.addNotice(errs, "areas")
        else:
            if self.use_areas is None:
                self.use_areas = "1"
            try:
                self.use_areas_list = parse_range(self.use_areas)
            except:
                errs = f"ERROR: Failed to parse areas range '{self.use_areas}'  will not add any areas: {sys.exc_info()[1]}"
                LOGGER.error(errs)
                self.addNotice(errs, "areas")
                self.config_st = False
        # Outputs
        self.use_outputs = self.getCustomParam("outputs")
        self.use_outputs_list = ()
        if self.use_outputs == "" or self.use_outputs is None:
            LOGGER.warning(
                "No outputs defined in config so none will be added")
        else:
            try:
                self.use_outputs_list = parse_range(self.use_outputs)
            except:
                errs = f"ERROR: Failed to parse outputs range '{self.use_outputs}'  will not add any outputs: {sys.exc_info()[1]}"
                LOGGER.error(errs)
                self.addNotice(errs, "outputs")
                self.config_st = False

        #self.use_keypads = self.getCustomParam("keypads")
        #self.use_keypads_list = ()
        #if self.use_keypads == "" or self.use_keypads is None:
        #    LOGGER.warning("No keypads defined in config so none will be added")
        #else:
        #    try:
        #        self.use_keypads_list = parse_range(self.use_keypads)
        #    except:
        #        errs = f"ERROR: Failed to parse keypads range '{self.use_keypads}'  will not add any keypads: {sys.exc_info()[1]}"
        #        LOGGER.error(errs)
        #        self.addNotice(errs, "keypads")
        #        self.config_st = False

        # Make sure they are in the params
        self.addCustomParam({
            "temperature_unit": self.temperature_unit,
            "host": self.host,
            "user_code": self.user_code,
            "areas": self.use_areas,
            "outputs": self.use_outputs,
            #"keypads": self.use_keypads
        })

        # Add a notice if they need to change the keypad/password from the default.
        if self.host == default_host:
            # This doesn't pass a key to test the old way.
            self.addNotice(
                "Please set proper host in configuration page, and restart this nodeserver",
                "host",
            )
            self.config_st = False
        if self.user_code == default_code:
            # This doesn't pass a key to test the old way.
            self.addNotice(
                "Please set proper user_code in configuration page, and restart this nodeserver",
                "code",
            )
            self.config_st = False
示例#19
0
 def start(self):
     LOGGER.info('Started Ecobee v2 NodeServer')
     self.removeNoticesAll()
     self.heartbeat()
     self.serverdata = get_server_data(LOGGER)
     LOGGER.info('Ecobee NodeServer Version {}'.format(self.serverdata['version']))
     nsv = 'nodeserver_version'
     ud  = False
     cust_data = self.polyConfig['customData']
     if not nsv in cust_data:
         LOGGER.info("Adding {}={} to customData".format(nsv,self.serverdata['version']))
         cust_data[nsv] = self.serverdata['version']
         ud = True
     elif cust_data[nsv] != self.serverdata['version']:
         LOGGER.info("Update {} from {} to {} in customData".format(nsv,cust_data[nsv],self.serverdata['version']))
         cust_data[nsv] = self.serverdata['version']
         ud = True
     # Delete the saved token data we were doing for a while
     # For PG3 we can start doing it again, but not in PG2 since it costs $$
     # Can't iterate over keys, since the keys get removed, causes python crash
     keys = list(cust_data.keys())
     for key in keys:
         if re.match('tokenData2020.*',key):
             LOGGER.info("Deleting old customData key {}".format(key))
             del cust_data[key]
     if ud:
         self.saveCustomDataWait(cust_data)
     #LOGGER.debug("init=\n"+json.dumps(self.poly.init,sort_keys=True,indent=2))
     LOGGER.debug("customData=\n"+json.dumps(cust_data,sort_keys=True,indent=2))
     self.set_debug_mode()
     self.get_session() 
     # Anything special to do in pgtest development mode?
     #if self.poly.init['development']:
     #
     # Cloud uses OAuth, local users PIN
     #
     self.pg_test = False
     if self._cloud:
         self.grant_type = 'authorization_code'
         self.api_key    = self.serverdata['api_key']
         # TODO: Need a better way to tell if we are on pgtest!
         #       "logBucket": "pgc-test-logbucket-19y0vctj4zlk5",
         if self.poly.stage == 'test':
             self.pg_test = True
             LOGGER.warning("Looks like we are running on to pgtest")
             self.redirect_url = 'https://pgtest.isy.io/api/oauth/callback'
         else:
             LOGGER.warning("Looks like we are running on to pgc")
             self.redirect_url = 'https://polyglot.isy.io/api/oauth/callback'
     else:
         self.grant_type = 'ecobeePin'
         self.api_key    = self.serverdata['api_key_pin']
         self.redirect_url = None
     # Force to false, and successful communication will fix it
     #self.set_ecobee_st(False) Causes it to always stay false.
     # Make sure they are using the latest API
     if self.check_api():
         if 'tokenData' in self.polyConfig['customData']:
             self.tokenData = self.polyConfig['customData']['tokenData']
             if self._checkTokens():
                 LOGGER.info("start: Calling discover...")
                 self.discover()
         else:
             LOGGER.info('No tokenData, will need to authorize...')
             self.authorize()
             self.reportDrivers()
     else:
         LOGGER.info('No tokenData, will need to authorize...')
         self._reAuth("Using old api key.")
     self.ready = True
     LOGGER.debug('done')