Beispiel #1
0
 def cmd_alert_off(self, command):
     LOGGER.info("")
     st = self.host.disable_alert(self.cam['id'])
     self.set_driver('MODE', 0)
Beispiel #2
0
 def cmd_discover(self, command):
     LOGGER.info(f"{self.lpfx}")
     return self.discover()
Beispiel #3
0
 def l_info(self, name, string):
     LOGGER.info("%s:%s: %s" %  (self.id,name,string))
Beispiel #4
0
 def process_config(self, config):
     # this seems to get called twice for every change, why?
     # What does config represent?
     LOGGER.info(f"{self.lpfx} Enter config={config}")
     LOGGER.info(f"{self.lpfx} process_config done")
Beispiel #5
0
 def update_profile(self):
     LOGGER.info(f"{self.lpfx}")
     return self.poly.installprofile()
Beispiel #6
0
 def disconnected(self):
     LOGGER.info(f"{self.lpfx} Disconnected!!!")
     self.set_st(False)
Beispiel #7
0
 def sync_complete(self):
     LOGGER.info(f"{self.lpfx} Sync of keypad is complete!!!")
     # TODO: Add driver for sync complete status, or put in ST?
     LOGGER.info(f"{self.lpfx} adding areas...")
     for an in range(Max.AREAS.value):
         if an in self._area_nodes:
             LOGGER.info(
                 f"{self.lpfx} Skipping Area {an+1} because it already defined."
             )
         elif is_in_list(an + 1, self.use_areas_list) is False:
             LOGGER.info(
                 f"{self.lpfx} Skipping Area {an+1} because it is not in areas range {self.use_areas} in configuration"
             )
         else:
             LOGGER.info(f"{self.lpfx} Adding Area {an}")
             self._area_nodes[an] = self.addNode(
                 AreaNode(self, self.elk.areas[an]))
     LOGGER.info("adding areas done, adding outputs...")
     # elkm1_lib uses zone numbers starting at zero.
     for n in range(Max.OUTPUTS.value):
         if n in self._output_nodes:
             LOGGER.info(
                 f"{self.lpfx} Skipping Output {n+1} because it already defined."
             )
         elif is_in_list(n + 1, self.use_outputs_list) is False:
             LOGGER.info(
                 f"{self.lpfx} Skipping Output {n+1} because it is not in outputs range {self.use_outputs} in configuration"
             )
         else:
             LOGGER.info(f"{self.lpfx} Adding Output {an}")
             self._output_nodes[an] = self.addNode(
                 OutputNode(self, self.elk.outputs[n]))
     LOGGER.info("adding outputs done")
     # Only update profile on restart
     if not self.profile_done:
         self.write_profile()
         self.profile_done = True
     self.ready = True
Beispiel #8
0
    def setclrflip(self, command):
        DEVICEID = "ebfc16d57ed374932cjqfk"
        DEVICEIP = "192.168.1.150"
        DEVICEKEY = "805217605357161b"
        DEVICEVERS = "us"
        # Check for environmental variables and always use those if available
        DDEVICEID = os.getenv("DEVICEID", DEVICEID)
        DEVICEIP = os.getenv("DEVICEIP", DEVICEIP)
        DEVICEKEY = os.getenv("DEVICEKEY", DEVICEKEY)
        DEVICEVERS = os.getenv("DEVICEVERS", DEVICEVERS)

        LOGGER.info("TreatLife - Smart Switch Test [%s]\n" %
                    tinytuya.__version__)
        LOGGER.info('TESTING: Device %s at %s with key %s version %s' %
                    (DEVICEID, DEVICEIP, DEVICEKEY, DEVICEVERS))

        LOGGER.info('TESTING: Device %s' % (DEVICEIP))

        d = tinytuya.BulbDevice(DEVICEID, DEVICEIP, DEVICEKEY)
        d.set_version(3.3)
        d.set_socketPersistent(True)

        # Turn on
        d.turn_on()
        self.setDriver('GV2', 1)
        time.sleep(1)

        # Dimmer Test
        LOGGER.info('\nDimmer Control Test')
        for level in range(11):
            LOGGER.info('    Level: %d%%' % (level * 10))
            d.set_brightness_percentage(level * 10)
            time.sleep(1)

        # Colortemp Test
        LOGGER.info('\nColortemp Control Test (Warm to Cool)')
        for level in range(11):
            LOGGER.info('    Level: %d%%' % (level * 10))
            d.set_colourtemp_percentage(level * 10)
            time.sleep(1)

        # Flip through colors of rainbow - set_colour(r, g, b):
        LOGGER.info('\nColor Test - Cycle through rainbow')
        rainbow = {
            "red": [255, 0, 0],
            "orange": [255, 127, 0],
            "yellow": [255, 200, 0],
            "green": [0, 255, 0],
            "blue": [0, 0, 255],
            "indigo": [46, 43, 95],
            "violet": [139, 0, 255]
        }
        for x in range(2):
            for i in rainbow:
                r = rainbow[i][0]
                g = rainbow[i][1]
                b = rainbow[i][2]
                LOGGER.info('    %s (%d,%d,%d)' % (i, r, g, b))
                d.set_colour(r, g, b)
                time.sleep(2)
            LOGGER.info('')

        # Turn off
        d.turn_off()
        time.sleep(1)

        # Random Color Test
        d.turn_on()
        LOGGER.info('\nRandom Color Test')
        for x in range(10):
            r = random.randint(0, 255)
            g = random.randint(0, 255)
            b = random.randint(0, 255)
            LOGGER.info('    RGB (%d,%d,%d)' % (r, g, b))
            d.set_colour(r, g, b)
            time.sleep(2)

        # Test Modes
        LOGGER.info('\nTesting Bulb Modes')
        LOGGER.info('    Colour')
        d.set_mode('colour')
        time.sleep(2)
        LOGGER.info('    Scene')
        d.set_mode('scene')
        time.sleep(2)
        LOGGER.info('    Music')
        d.set_mode('music')
        time.sleep(2)
        LOGGER.info('    White')
        d.set_mode('white')
        time.sleep(2)

        # Turn off
        d.turn_off()
        self.setDriver('GV2', 0)
        time.sleep(1)
        LOGGER.info('\nDone')
Beispiel #9
0
    def colorOn(self, command):
        DEVICEID = "ebfc16d57ed374932cjqfk"
        DEVICEIP = "192.168.1.150"
        DEVICEKEY = "805217605357161b"
        DEVICEVERS = "us"
        # Check for environmental variables and always use those if available
        DDEVICEID = os.getenv("DEVICEID", DEVICEID)
        DEVICEIP = os.getenv("DEVICEIP", DEVICEIP)
        DEVICEKEY = os.getenv("DEVICEKEY", DEVICEKEY)
        DEVICEVERS = os.getenv("DEVICEVERS", DEVICEVERS)

        LOGGER.info("TreatLife - Smart Switch Test [%s]\n" %
                    tinytuya.__version__)
        LOGGER.info('TESTING: Device %s at %s with key %s version %s' %
                    (DEVICEID, DEVICEIP, DEVICEKEY, DEVICEVERS))

        LOGGER.info('TESTING: Device %s' % (DEVICEIP))

        d = tinytuya.BulbDevice(DEVICEID, DEVICEIP, DEVICEKEY)
        d.set_version(3.3)
        d.set_socketPersistent(True)
        self.colorOn = int(command.get('value'))
        self.setDriver('GV5', self.colorOn)
        if self.colorOn == 0:
            d.set_colour(255, 0, 0)
            LOGGER.info('Red')
        elif self.colorOn == 1:
            d.set_colour(255, 127, 0)
            LOGGER.info('Orange')
        elif self.colorOn == 2:
            d.set_colour(255, 200, 0)
            LOGGER.info('Yellow')
        elif self.colorOn == 3:
            d.set_colour(0, 255, 0)
            LOGGER.info('Green')
        elif self.colorOn == 4:
            d.set_colour(0, 0, 255)
            LOGGER.info('Blue')
        elif self.colorOn == 5:
            d.set_colour(46, 43, 95)
            LOGGER.info('Indigo')
        elif self.colorOn == 6:
            d.set_colour(139, 0, 255)
            LOGGER.info('Violet')
        elif self.colorOn == 7:
            d.set_colour(255, 255, 255)
            LOGGER.info('White')
Beispiel #10
0
    def process_config(self, config):
        if not self.isStarted:
            self.config = config
            return

        typedConfig = config.get('typedCustomData')
        if typedConfig is None:
            LOGGER.info('Config is not set')
            return

        if self.service is None:
            if len(typedConfig.get('token')) == 0:
                LOGGER.warn('Token is not set')
                return

            try:
                self.flow.fetch_token(code=typedConfig.get('token'))
                with open('token.pickle', 'wb') as token:
                    pickle.dump(self.flow.credentials, token)
                self.credentials = self.flow.credentials
                self.openService()
                self.removeNotice('auth')
            except Exception as e:
                LOGGER.error('Error getting credentials: %s', e)
                return

        LOGGER.debug('Reading calendar configuration')
        self.calendars = []

        calendarList = {}
        pageToken = None
        while True:
            list = self.service.calendarList().list(
                pageToken=pageToken).execute()
            for listEntry in list['items']:
                # LOGGER.debug('Found calendar %s %s', listEntry['summary'], listEntry)
                calendarList[listEntry['summary']] = listEntry
                pageToken = list.get('nextPageToken')
            if not pageToken:
                break

        list = typedConfig.get('calendarName')
        calendarIndex = 0
        if list is not None:
            for calendarName in list:
                calendar = calendarList.get(calendarName)
                if calendar is None:
                    LOGGER.error('Cannot find configured calendar name %s',
                                 calendarName)
                else:
                    entry = CalendarEntry(
                        calendar,
                        DayNode(self, self.address,
                                'today' + str(calendarIndex),
                                calendar['summary'] + ' Today'),
                        DayNode(self, self.address,
                                'tmrow' + str(calendarIndex),
                                calendar['summary'] + ' Tomorrow'))
                    self.calendars.append(entry)
                    self.addNode(entry.todayNode)
                    self.addNode(entry.tomorrowNode)

                    calendarIndex += 1

        if calendarList.keys() != self.calendarList:
            self.calendarList = calendarList.keys()
            data = '<h3>Configured Calendars</h3><ul>'
            for calendarName in self.calendarList:
                data += '<li>' + calendarName + '</li>'
            data += '</ul>'
            self.poly.add_custom_config_docs(data, True)

        self.refresh()
Beispiel #11
0
    def start(self):
        DEVICEID = "017743508caab5f385a7"
        DEVICEIP = "192.168.1.148"
        DEVICEKEY = "7b8f2415ac96dfea"
        DEVICEVERS = "us"
        LOGGER.info(DEVICEID)
        LOGGER.info(DEVICEIP)
        LOGGER.info(DEVICEKEY)
        #LOGGER.info('us')

        # Check for environmental variables and always use those if available
        DEVICEID = os.getenv("DEVICEID", DEVICEID)
        DEVICEIP = os.getenv("DEVICEIP", DEVICEIP)
        DEVICEKEY = os.getenv("DEVICEKEY", DEVICEKEY)
        DEVICEVERS = os.getenv("DEVICEVERS", DEVICEVERS)

        LOGGER.info("TreatLife - Smart Switch Test [%s]\n" %
                    tinytuya.__version__)
        LOGGER.info('TESTING: Device %s at %s with key %s version %s' %
                    (DEVICEID, DEVICEIP, DEVICEKEY, DEVICEVERS))

        LOGGER.info('TESTING: Device %s' % (DEVICEIP))

        d = tinytuya.OutletDevice(DEVICEID, DEVICEIP, DEVICEKEY)
        d.set_version(3.3)
Beispiel #12
0
 def delete(self):
     LOGGER.info(
         'Oh God I\'m being deleted. Nooooooooooooooooooooooooooooooooooooooooo.'
     )
Beispiel #13
0
 def disable_alert(self, cam_id):
     LOGGER.info(f"{self.lpfx}: {cam_id}")
     return self.camect.disable_alert([cam_id], "nodeserver")
    def get_certificate(self):
        LOGGER.info("Getting certificate")
        try:
            with open('./caseta.crt', 'rb') as f:
                certificate = x509.load_pem_x509_certificate(f.read(),
                                                             default_backend())
            LOGGER.info("Loaded cert from disk")
        except FileNotFoundError:
            LOGGER.info("Generating certificate request")
            csr = (x509.CertificateSigningRequestBuilder()
                   .subject_name(CERT_SUBJECT)
                   .sign(self.private_key, hashes.SHA256(), default_backend()))

            if not self.oauth_code:
                LOGGER.error('No OAUTH code stored, exiting')
                return None

            LOGGER.info("requesting token...")
            token = requests.post("%soauth/token" % BASE_URL, data={
                "code": self.oauth_code,
                "client_id": APP_CLIENT_ID,
                "client_secret": APP_CLIENT_SECRET,
                "redirect_uri": REDIRECT_URI,
                "grant_type": "authorization_code"}).json()

            if token["token_type"] != "bearer":
                raise ("Received invalid token %s. Try generating a new code "
                       "(one time use).") % token

            access_token = token["access_token"]

            pairing_request_content = {
                "remote_signs_app_certificate_signing_request":
                csr.public_bytes(serialization.Encoding.PEM).decode('ASCII')
            }

            LOGGER.info("sending pairing request")
            pairing_response = requests.post(
                "%sapi/v1/remotepairing/application/user" % BASE_URL,
                json=pairing_request_content,
                headers={
                    "X-DeviceType": "Caseta,RA2Select",
                    "Authorization": "Bearer %s" % access_token
                }
            ).json()

            app_cert = pairing_response["remote_signs_app_certificate"]
            remote_cert = pairing_response["local_signs_remote_certificate"]

            LOGGER.info("storing certificate to disk")
            with open('caseta.crt', 'wb') as f:
                f.write(app_cert.encode('ASCII'))
                f.write(remote_cert.encode('ASCII'))

            # TODO Don't open new filehandle to read cert back
            LOGGER.info("reading certificate back from disk")
            with open('caseta.crt', 'rb') as f:
                certificate = x509.load_pem_x509_certificate(f.read(),
                                                             default_backend())

        return certificate
Beispiel #15
0
    def tuyaPlatform(self, apiRegion, apiKey, apiSecret, uri, token=None):
        request = "https://openapi.tuya%s.com/v1.0/%s" % (apiRegion, uri)
        now = int(time.time() * 1000)
        if (token == None):
            payload = apiKey + str(now)
        else:
            payload = apiKey + token + str(now)

        # Sign Payload
        signature = hmac.new(apiSecret.encode('utf-8'),
                             msg=payload.encode('utf-8'),
                             digestmod=hashlib.sha256).hexdigest().upper()

        # Create Header Data
        headers = {}
        headers['client_id'] = apiKey
        headers['sign_method'] = 'HMAC-SHA256'
        headers['t'] = str(now)
        headers['sign'] = signature
        if (token != None):
            headers['access_token'] = token

        # Get Token
        response = requests.get(request, headers=headers)
        try:
            response_dict = json.loads(response.content.decode())
        except:
            try:
                response_dict = json.loads(response.content)
            except:
                LOGGER.debug("Failed to get valid JSON response")

        #return(response_dict)

    #def wizard(self, command, color=True):
        config = {}
        config['apiKey'] = 'default_apiKey'  #'txejpdfda9iwmn5cg2es'
        config[
            'apiSecret'] = 'default_apiSecret'  #'46d6072ffd724e0ba5ebeb5cc6b9dce9'
        config['apiRegion'] = 'us'
        config['apiDeviceID'] = 'default_apiDeviceId'  #'017743508caab5f0973e'
        needconfigs = True

        if (config['apiKey'] != '' and config['apiSecret'] != ''
                and config['apiRegion'] != '' and config['apiDeviceID'] != ''):
            needconfigs = False
            answer = 'Y'  #input(subbold + '    Use existing credentials ' +
            #     normal + '(Y/n): ')
            if ('Y'[0:1].lower() == 'n'):
                needconfigs = True

        KEY = config['apiKey']
        SECRET = config['apiSecret']
        DEVICEID = config['apiDeviceID']
        REGION = config['apiRegion']  # us, eu, cn, in
        LANG = 'en'  # en or zh

        # Get Oauth Token from tuyaPlatform
        uri = 'token?grant_type=1'
        response_dict = tuyaPlatform(REGION, KEY, SECRET, uri)
        token = response_dict['result']['access_token']

        # Get UID from sample Device ID
        uri = 'devices/%s' % DEVICEID
        response_dict = tuyaPlatform(REGION, KEY, SECRET, uri, token)
        uid = response_dict['result']['uid']

        # Use UID to get list of all Devices for User
        uri = 'users/%s/devices' % uid
        json_data = tuyaPlatform(REGION, KEY, SECRET, uri, token)
        response_dict = response_dict

        # Filter to only Name, ID and Key
        tuyadevices = []
        for i in json_data['result']:
            item = {}
            item['name'] = i['name'].strip()
            item['id'] = i['id']
            item['key'] = i['local_key']
            tuyadevices.append(item)

        #Display device list
        LOGGER.info("\n\n" + "Device Listing\n")
        output = json.dumps(tuyadevices, indent=4)  # sort_keys=True)
        LOGGER.info(output)

        # Save list to devices.json
        ##LOGGER.info(bold + "\n>> " + normal + "Saving list to " + DEVICEFILE)
        ##with open(DEVICEFILE, "w") as outfile:
        ##    outfile.write(output)
        ##LOGGER.info(dim + "    %d registered devices saved" % len(tuyadevices))

        if ('Y'[0:1].lower() != 'n'):
            # Scan network for devices and provide polling data
            ##LOGGER.info(normal + "\nScanning local network for Tuya devices...")
            devices = tinytuya.deviceScan(False, 20)

            ##LOGGER.info("    %s%s local devices discovered%s" %
            ##      (len(devices)))
            ##LOGGER.info("")

            def getIP(d, gwid):
                for ip in d:
                    if (gwid == d[ip]['gwId']):
                        return (ip, d[ip]['version'])
                return (0, 0)

            polling = []
        LOGGER.info("Polling local devices...")
        for i in tuyadevices:
            item = {}
            name = i['name']
            (ip, ver) = getIP(devices, i['id'])
            item['name'] = name
            item['ip'] = ip
            item['ver'] = ver
            item['id'] = i['id']
            item['key'] = i['key']
            if (ip == 0):
                LOGGER.info("    %s[%s] - %s%s - %sError: No IP found%s" %
                            (name, ip, name))
            else:
                try:
                    d = tinytuya.OutletDevice(i['id'], ip, i['key'])
                    if ver == "3.3":
                        d.set_version(3.3)
                    data = d.status()
                    if 'dps' in data:
                        item['devId'] = data
                        #state = alertdim + "Off"
                        try:
                            if '1' in data['dps'] or '20' in data[
                                    'devId'] or '1' in data['dps']:

                                #state = "On"
                                #LOGGER.info("    %s[%s] - %s%s - %s - DPS: %r" %
                                #    (name, ip, state, data['dps'])
                                LOGGER.info(
                                    "\nEACH TREATLIFE SWITCH TO NODE WITH ADDNODE FROM HERE!!!"
                                )
                                LOGGER.info(
                                    "%-35.35s %-24s %-16s %-17s %-5s" %
                                    (item["name"], item["id"], item["ip"],
                                     item["key"], item["ver"]))
                            else:
                                #LOGGER.info("    %s[%s] - %s%s - DPS: %r" %
                                #    (name, ip, data['dps']))
                                pass
                        except:
                            #print("    %s[%s] - %s%s - %sNo Response" %
                            #      (subbold, name, dim, ip, alertdim))
                            pass
                    else:
                        #print("    %s[%s] - %s%s - %sNo Response" %
                        #      (subbold, name, dim, ip, alertdim))
                        pass
                except:
                    pass
                    #print("    %s[%s] - %s%s - %sNo Response" %
                    #      (subbold, name, dim, ip, alertdim))
            polling.append(item)
        # for loop

        # Save polling data snapsot
        current = {'timestamp': time.time(), 'devices': polling}
        output = json.dumps(current, indent=4)
        SWITCHID = i['id']
        SWITCHIP = item["ip"]
        SWITCHKEY = item["key"]
        LOGGER.info("Currently Passed Name:", 'item'["name"])
        LOGGER.info('SWITCHID')  # Device Name
        #LOGGER.info(SWITCHIP) # Device IP
        #LOGGER.info(SWITCHKEY)
        LOGGER.info("TEST1 ID" + 'item'["id"])  # Device ID
        LOGGER.info("TEST1 KEY" + 'item'["key"])  # Device Key
Beispiel #16
0
    def modeOn(self, command):
        DEVICEID = "ebfc16d57ed374932cjqfk"
        DEVICEIP = "192.168.1.150"
        DEVICEKEY = "805217605357161b"
        DEVICEVERS = "us"
        # Check for environmental variables and always use those if available
        DDEVICEID = os.getenv("DEVICEID", DEVICEID)
        DEVICEIP = os.getenv("DEVICEIP", DEVICEIP)
        DEVICEKEY = os.getenv("DEVICEKEY", DEVICEKEY)
        DEVICEVERS = os.getenv("DEVICEVERS", DEVICEVERS)

        LOGGER.info("TreatLife - Smart Switch Test [%s]\n" %
                    tinytuya.__version__)
        LOGGER.info('TESTING: Device %s at %s with key %s version %s' %
                    (DEVICEID, DEVICEIP, DEVICEKEY, DEVICEVERS))

        LOGGER.info('TESTING: Device %s' % (DEVICEIP))

        d = tinytuya.BulbDevice(DEVICEID, DEVICEIP, DEVICEKEY)
        d.set_version(3.3)
        d.set_socketPersistent(True)
        self.modeOn = int(command.get('value'))
        self.setDriver('GV4', self.modeOn)
        if self.modeOn == 0:
            d.set_mode('colour')
            LOGGER.info('Colour')
        elif self.modeOn == 1:
            d.set_mode('scene')
            LOGGER.info('Scene')
        elif self.modeOn == 2:
            d.set_mode('music')
            LOGGER.info('Music')
        elif self.modeOn == 3:
            d.set_mode('white')
            LOGGER.info('White')
Beispiel #17
0
 def connected(self):
     LOGGER.info(f"{self.lpfx} Connected!!!")
     self.set_st(True)
Beispiel #18
0
    def wizard(self, command, color=True):

        color = True
        ### Credentials Needed
        # Get Configuration Data
        CONFIGFILE = 'tinytuya.json'
        #DEVICEFILE = 'devices.json'
        #SNAPSHOTFILE = 'snapshot.json'
        config = {}
        config['apiKey'] = 'default_apiKey'  #'txejpdfda9iwmn5cg2es'
        config[
            'apiSecret'] = 'default_apiSecret'  #'46d6072ffd724e0ba5ebeb5cc6b9dce9'
        config['apiRegion'] = 'us'
        config['apiDeviceID'] = 'default_apiDeviceId'  #'017743508caab5f0973e'
        needconfigs = True
        try:
            # Load defaults
            with open(CONFIGFILE) as f:
                config = json.load(f)
        except:
            # First Time Setup
            pass

        if (color == False):
            # Disable Terminal Color Formatting
            bold = subbold = normal = dim = alert = alertdim = ""
        else:
            # Terminal Color Formatting
            bold = "\033[0m\033[97m\033[1m"
            subbold = "\033[0m\033[32m"
            normal = "\033[97m\033[0m"
            dim = "\033[0m\033[97m\033[2m"
            alert = "\033[0m\033[91m\033[1m"
            alertdim = "\033[0m\033[91m\033[2m"

        KEY = config['apiKey']
        SECRET = config['apiSecret']
        DEVICEID = config['apiDeviceID']
        REGION = config['apiRegion']  # us, eu, cn, in
        LANG = 'en'  # en or zh

        # Get Oauth Token from tuyaPlatform
        uri = 'token?grant_type=1'
        response_dict = tuyaPlatform(REGION, KEY, SECRET, uri)
        token = response_dict['result']['access_token']

        # Get UID from sample Device ID
        uri = 'devices/%s' % DEVICEID
        response_dict = tuyaPlatform(REGION, KEY, SECRET, uri, token)
        uid = response_dict['result']['uid']

        # Use UID to get list of all Devices for User
        uri = 'users/%s/devices' % uid
        json_data = tuyaPlatform(REGION, KEY, SECRET, uri, token)

        # Filter to only Name, ID and Key
        tuyadevices = []
        for i in json_data['result']:
            item = {}
            item['name'] = i['name'].strip()
            item['id'] = i['id']
            item['key'] = i['local_key']
            tuyadevices.append(item)

        #Display device list
        #LOGGER.info("\n\n" + bold + "Device Listing\n" + dim)
        #output = json.dumps(tuyadevices, indent=4)  # sort_keys=True)
        #LOGGER.info(output)

        # Save list to devices.json
        ##LOGGER.info(bold + "\n>> " + normal + "Saving list to " + DEVICEFILE)
        ##with open(DEVICEFILE, "w") as outfile:
        ##    outfile.write(output)
        ##LOGGER.info(dim + "    %d registered devices saved" % len(tuyadevices))

        if ('Y'[0:1].lower() != 'n'):
            # Scan network for devices and provide polling data
            LOGGER.info(normal +
                        "\nScanning local network for Tuya devices...")
            devices = tinytuya.deviceScan(False, 20)
            LOGGER.info("    %s%s local devices discovered%s" %
                        (dim, len(devices), normal))
            LOGGER.info("")

            def getIP(d, gwid):
                for ip in d:
                    if (gwid == d[ip]['gwId']):
                        return (ip, d[ip]['version'])
                return (0, 0)

            polling = []
            LOGGER.info("Polling local devices...")
            for i in tuyadevices:
                item = {}
                name1 = i['name']
                id1 = i['id']
                key1 = i['key']
                item['key'] = key1
                (ip, ver) = getIP(devices, i['id'])
                item['name'] = name1
                item['ip'] = ip
                item['ver'] = ver
                item['id'] = i['id']
                item['key'] = i['key']
                if (ip == 0):
                    LOGGER.info("    %s[%s] - %s%s - %sError: No IP found%s" %
                                (subbold, name, dim, ip, alert, normal))
                else:
                    try:
                        d = tinytuya.OutletDevice(i['id'], ip, i['key'])
                        if ver == "3.3":
                            d.set_version(3.3)
                        data = d.status()
                        if data:
                            item['dps'] = data
                            state = alertdim + "Off" + dim
                            # LOGGER.info(data)
                            try:
                                if (data['dps']['1'] == True):
                                    state = bold + "On" + dim
                                LOGGER.info(
                                    'WOW' +
                                    "    %s[%s] - %s%s - %s - DPS: %r" %
                                    (subbold, name, dim, ip, state,
                                     data['dps']))
                            except:
                                pass
                                #LOGGER.info("    %s[%s] - %s%s - %sNo Response" %
                                #      (subbold, name, dim, ip, alertdim))
                        else:
                            pass
                            #LOGGER.info("    %s[%s] - %s%s - %sNo Response" %
                            #      (subbold, name, dim, ip, alertdim))
                    except:
                        pass
                        #LOGGER.info("    %s[%s] - %s%s - %sNo Response" %
                        #      (subbold, name, dim, ip, alertdim))
                polling.append(item)

        return
        # for loop

        # Save polling data snapsot
        ##current = {'timestamp' : time.time(), 'devices' : polling}
        ##output = json.dumps(current, indent=4)
        ##LOGGER.info(bold + "\n>> " + normal + "Saving device snapshot data to " + SNAPSHOTFILE)
        ##with open(SNAPSHOTFILE, "w") as outfile:
        ##    outfile.write(output)
        ### addNode
        #if(data['dps']['1']==True):
        #   state = bold + "On" + dim
        #  LOGGER.debug("    %s[%s] - %s%s - %s - DPS: %r" %
        #(subbold, name, dim, ip, state, data['dps']))

        #LOGGER.info("\nDone Polling Switches.\n")
        #return
        LOGGER.info(name)  # Device Name
        LOGGER.info('TESTING1: Device ip %s' % (ip))
        LOGGER.info(ip)  # Device IP
        LOGGER.info(id1)  # Device ID
        LOGGER.info(key1)  # Device Key
Beispiel #19
0
 def login(self, succeeded):
     if succeeded:
         LOGGER.info("Login succeeded")
     else:
         LOGGER.error(f"{self.lpfx} Login Failed!!!")
Beispiel #20
0
    def start(self):
        DEVICEID = "017743508caab5f0973e"
        DEVICEIP = "192.168.1.139"
        DEVICEKEY = "e779c96c964f71b2"
        DEVICEVERS = "us"
        LOGGER.info(DEVICEID)
        LOGGER.info(DEVICEIP)
        LOGGER.info(DEVICEKEY)
        LOGGER.info('us')

        # Check for environmental variables and always use those if available
        DEVICEID = os.getenv("DEVICEID", DEVICEID)
        DEVICEIP = os.getenv("DEVICEIP", DEVICEIP)
        DEVICEKEY = os.getenv("DEVICEKEY", DEVICEKEY)
        DEVICEVERS = os.getenv("DEVICEVERS", DEVICEVERS)

        LOGGER.info("TinyTuya - Smart Bulb RGB Test High [%s]\n" %
                    tinytuya.__version__)
        LOGGER.info('TESTING: Device %s at %s with key %s version %s' %
                    (DEVICEID, DEVICEIP, DEVICEKEY, DEVICEVERS))

        LOGGER.info('TESTING: Device %s' % (DEVICEIP))

        #LOGGER.info('TESTING: Device %s' %
        #            (ip))

        #self.setDriver('ST', 1)

        # Connect to the device - replace with real values
        d = tinytuya.OutletDevice(DEVICEID, DEVICEIP, DEVICEKEY)
        d.set_version(3.3)

        # Generate the payload to send - add all the DPS values you want to change here
        #if data != [0]:
        payload1 = d.generate_payload(tinytuya.CONTROL, {'1': False, '2': 50})
        #    time.sleep(2)
        payload2 = d.generate_payload(tinytuya.CONTROL, {'1': True, '2': 50})
        #    time.sleep(2)

        #payload1=d.generate_payload(tinytuya.CONTROL, {'1': False, '2': 50})
        #payload2=d.generate_payload(tinytuya.CONTROL, {'1': True, '2': 50})

        # Send the payload to the device

        #d._send_receive(payload1)
        #time.sleep(2)
        #d._send_receive(payload2)

        #LOGGER.info(str(ip).upper())

        # Get the status of the device
        #response = requests.request("GET", url, headers=headers, data=payload)
        #LOGGER.info('Response. Using {}'str(d._send_receive(payload)))

        # Command for
        # Show status of device

        #self.setDriver('GV2', data, force=True)
        data = d.status()
        LOGGER.info('\nCurrent Status of Switch: %r' % data)  #%r
Beispiel #21
0
 def delete(self):
     LOGGER.info(
         f"{self.lpfx} Oh no I am being deleted. Nooooooooooooooooooooooooooooooooooooooooo."
     )
Beispiel #22
0
 def delete(self):
     LOGGER.info('Removing Tuya Switch.')
Beispiel #23
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
Beispiel #24
0
 def process_config(self, config):
     # this seems to get called twice for every change, why?
     # What does config represent?
     LOGGER.info("process_config: Enter config={}".format(config))
     LOGGER.info("process_config: Exit")
Beispiel #25
0
 def cmd_update_profile(self, command):
     LOGGER.info(f"{self.lpfx}")
     return self.update_profile()
Beispiel #26
0
 def remove_notices_all(self, command):
     LOGGER.info('remove_notices_all: notices={}'.format(
         self.poly.config['notices']))
     # Remove all existing notices
     self.removeNoticesAll()
Beispiel #27
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
Beispiel #28
0
 def update_profile(self, command):
     LOGGER.info('update_profile:')
     st = self.poly.installprofile()
     return st
Beispiel #29
0
    def start(self):
        """
        Optional.
        Polyglot v2 Interface startup done. Here is where you start your integration.
        This will run, once the NodeServer connects to Polyglot and gets it's config.
        In this example I am calling a discovery method. While this is optional,
        this is where you should start. No need to Super this method, the parent
        version does nothing.
        """
        self.removeNoticesAll()
        serverdata = self.poly.get_server_data(check_profile=False)
        LOGGER.info('Started HarmonyHub NodeServer {}'.format(serverdata['version']))
                #polyinterface.LOGGER("start: This is {0} error {1}".format("an"))
        self.l_info('start','Starting')
        # Some are getting unclosed socket warnings from sleekxmpp when thread exits that I can't get rid if so ignore them.
        warnings.filterwarnings("ignore", category=ResourceWarning, message="unclosed.*<socket.socket.*>")
        # Show these for now
        self.l_debug("start","GV4={0} GV8={1}".format(self.getDriver('GV4'),self.getDriver('GV8')))
        self.set_debug_level(self.getDriver('GV4'))
        # Set Profile Status as Up To Date, if it's status 6=ISY Reboot Required
        val = self.getDriver('GV7')
        if val is None or int(val) == 6 or int(val) == 0:
            self.setDriver('GV7', 1)
        # Short Poll
        val = self.getDriver('GV5')
        self.l_debug("start","shortPoll={0} GV5={1}".format(self.polyConfig['shortPoll'],val))
        if val is None:
            self.setDriver('GV5',self.polyConfig['shortPoll'])
        elif (int(val) != 0):
            self.polyConfig['shortPoll'] = int(val)
        # Long Poll
        val = self.getDriver('GV6')
        self.l_debug("start","longPoll={0} GV6={1}".format(self.polyConfig['longPoll'],val))
        if val is None:
            self.setDriver('GV6',self.polyConfig['longPoll'])
        elif (int(val) != 0):
            self.polyConfig['longPoll'] = int(val)
        # Activiy method
        val = self.getDriver('GV9')
        if val is None:
            self.activity_method = 2 # The default
            self.setDriver('GV9',self.activity_method)
        else:
            self.activity_method = int(val)
        self.l_debug("start","GV9={0} activity_method={1}".format(val,self.activity_method))
        # Initialize hubs
        self.clear_hubs()
        # Load em if we have em
        self.load_hubs()
        # Watch Mode
        self.set_watch_mode(self.getDriver('GV10'))

        # New vesions need to force an update
        if not 'cver' in self.polyConfig['customData']:
            self.polyConfig['customData']['cver'] = 1
        self.l_debug("start","cver={0}".format(self.polyConfig['customData']['cver']))
        if int(self.polyConfig['customData']['cver']) < 2:
            self.l_debug("start","updating myself since cver {0} < 2".format(self.polyConfig['customData']['cver']))
            # Force an update.
            self.addNode(self,update=True)
            self.polyConfig['customData']['cver'] = 3
            self.saveCustomData(self.polyConfig['customData'])
        #
        # Add Hubs from the config
        #
        self._set_num_hubs(0)
        self.first_run = False
        #self.l_debug("start","nodes={}".format(self.polyConfig['nodes']))
        if self.polyConfig['nodes']:
            self.l_info("start","Adding known hubs...")
            # Load the config info about the hubs.
            self.load_config()
            # Load the hub info.
            self.load_hubs()
            if self.hubs is False:
                self.l_error("start","No hubs loaded, need to discover?")
                return
            # Build/Update profile if necessary
            serverdata = self.poly.check_profile(serverdata,build_profile=self._update_profile)
            # Restore known hubs from the poly config nodes
            self.add_hubs()
        else:
            # No nodes exist, that means this is the first time we have been run
            # after install, so do a discover
            self.l_info("start","First run, will start discover...")
            self.first_run = True
            self.discover()
        self.l_info("start","done")
 def delete(self):
     LOGGER.info('Removing Bas Garage Doors NodeServer')