def cmd_alert_off(self, command): LOGGER.info("") st = self.host.disable_alert(self.cam['id']) self.set_driver('MODE', 0)
def cmd_discover(self, command): LOGGER.info(f"{self.lpfx}") return self.discover()
def l_info(self, name, string): LOGGER.info("%s:%s: %s" % (self.id,name,string))
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")
def update_profile(self): LOGGER.info(f"{self.lpfx}") return self.poly.installprofile()
def disconnected(self): LOGGER.info(f"{self.lpfx} Disconnected!!!") self.set_st(False)
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
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')
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')
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()
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)
def delete(self): LOGGER.info( 'Oh God I\'m being deleted. Nooooooooooooooooooooooooooooooooooooooooo.' )
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
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
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')
def connected(self): LOGGER.info(f"{self.lpfx} Connected!!!") self.set_st(True)
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
def login(self, succeeded): if succeeded: LOGGER.info("Login succeeded") else: LOGGER.error(f"{self.lpfx} Login Failed!!!")
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
def delete(self): LOGGER.info( f"{self.lpfx} Oh no I am being deleted. Nooooooooooooooooooooooooooooooooooooooooo." )
def delete(self): LOGGER.info('Removing Tuya Switch.')
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
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")
def cmd_update_profile(self, command): LOGGER.info(f"{self.lpfx}") return self.update_profile()
def remove_notices_all(self, command): LOGGER.info('remove_notices_all: notices={}'.format( self.poly.config['notices'])) # Remove all existing notices self.removeNoticesAll()
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
def update_profile(self, command): LOGGER.info('update_profile:') st = self.poly.installprofile() return st
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')