def client_thread(conn, addr): conn.settimeout(7) conn.setblocking(1) try: #conn.setblocking(0) i =0 while API.threadRun: ready = False time.sleep(0.2) try: data = conn.recv(1024) if not data: break #print(data) jsonObj = json.loads(data.decode('utf-8')) if ('token' not in jsonObj or jsonObj['token'] != API.token): conn.send(json.dumps({"errcode": "2003", "msg": "Wrong API token"}).encode()) conn.close() else: payload = jsonObj['data'] if ('cmd' in payload): cmd = payload['cmd'] if (cmd == 'device.value.set'): device = Device.findDeviceById(payload['unitId'],payload['setId']) Log.i('API/OnValueACK',"Is device online: %i"%device.isOnline) while(API.socketAwaitACK !=None): continue if (device != None): API.socketAwaitACK = conn device.setValue(payload['value'].strip(), callback=API.onValueSetACK) else: conn.send(json.dumps({"errcode": "3002", "msg": "No such device", "payload":payload}).encode()) elif (cmd == 'device.value.schedule'): device = Device.findDeviceById(payload['unitId'],payload['setId']) Log.i('API/OnValueSchedule',"Is device online: %i"%device.isOnline) if (device != None): value = payload['value'].strip() print("'",value,"'") date = payload['date'] unid = device.unid setid = device.setid scriptStr = f''' newVal = '{value}' unit = Device.findDeviceById('{unid}','{setid}') smsStr = 'sms,all,*' if unit != None: unit.setValue(newVal) smsStr = smsStr + 'Value {value} set ok' else: smsStr = smsStr + 'Error setting value {value}' modems = Device.findDeviceById('0078','') if len(modems)>0: for key, modem in modems.items(): modem.setValue(smsStr) ''' uscript = ''.join(random.choice(string.ascii_uppercase + string.digits) for i in range(5))+".py" dir = common.config['HubServer']['USCRIPTS_PATH']+'Temp/' path = dir+uscript if not os.path.exists(dir): os.makedirs(dir) outFile = open(path, "w+", encoding="utf-8") outFile.write(scriptStr) outFile.close() DB.sqlInsert(f""" INSERT INTO `schedule` ( `type`, `time`, `lastTimeRun`, `nextTimeRun`, `script_name`, `active` ) VALUES ( '1', '{date}', '', '', '{uscript}', '1' ); """) from Tasker import Task Task.getAllTasks() conn.send(json.dumps({"errcode": "0", "data": {}}).encode()) else: conn.send(json.dumps({"errcode": "3002", "msg": "No such device", "payload":payload}).encode()) elif (cmd == 'device.conf.set'): device = Device.findDeviceById(payload['unitId'],payload['setId']) Log.i('API/OnValueACK',"Is device online: %i"%device.isOnline) while(API.socketAwaitACK !=None): continue if (device != None): if(device.isOnline): API.socketAwaitACK = conn device.setSettings(payload['value'], callback=API.onValueSetACK) else: conn.send(json.dumps({"errcode": "3003", "msg": "Device offline", "payload":payload}).encode()) else: conn.send(json.dumps({"errcode": "3002", "msg": "No such device", "payload":payload}).encode()) elif (cmd == 'device.reg.notif'): unid = payload['unitId'] setid = payload['setId'] devices = Device.findDeviceById(unid) msg = Msg(unid = unid, setid = setid, cmd="device.reg.notif") while(API.socketAwaitACK !=None): continue isNeedAll = True Log.d("API/NotifyNew",devices) for key, device in devices.items(): if(device.mySocketWrap != None): API.socketAwaitACK = conn device.mySocketWrap.sendMsg(msg) isNeedAll = False break Log.d("API/NotifyNew","[4]Point") if isNeedAll: for socketWrap in SocketWrap.allSockets: socketWrap.sendMsg(msg) #print("Disc/Is device online",SocketWrap.allUnits["00B40172"].isOnline) conn.send(json.dumps({"errcode": "0", "data": {}}).encode()) elif ('wifi.update' in cmd): interface = 'wlan0' name = payload['ssid'] password = payload['password'] os.system('iwconfig ' + interface + ' essid ' + name + ' key ' + password) conn.send(json.dumps({"errcode": "0", "data": {}}).encode()) elif ('config.update' in cmd): if ('db' in cmd): common.config.set('DataBase', 'HOST', payload['host']) common.config.set('DataBase', 'USER', payload['login']) common.config.set('DataBase', 'PASSW', payload['password']) common.config.set('DataBase', 'DB', payload['dbname']) common.config.set('DataBase', 'CHARSET', payload['charset']) DB.close() DB.start() Log.i('API/ConfigUpdate/DB',"MySQL reconnect") conn.send(json.dumps({"errcode": "0", "data": {}}).encode()) elif ('schedule.update' in cmd): from Tasker import Task Task.getAllTasks() conn.send(json.dumps({"errcode": "0", "data": {}}).encode()) elif ('uscript.run' in cmd): from Tasker import Task res = Task.runUserScriptEnv(payload['uscript']) conn.send(json.dumps({"errcode": "0", "data": res}).encode()) elif (cmd == 'system.stat.get'): response = {} response['Hub_version'] = common.config['HubServer']['VERSION'] if ('PortalConnect' in common.config): response['Hub_id'] = common.config['PortalConnect']['id'] response['CPU_load'] = str(psutil.cpu_percent()) + '%' memory = psutil.virtual_memory() # Divide from Bytes -> KB -> MB available = round(memory.available/1024.0/1024.0,1) total = round(memory.total/1024.0/1024.0,1) response['Memory'] = str(available) + 'MB free / ' + str(total) + 'MB total ( ' + str(memory.percent) + '% )' disk = psutil.disk_usage('/') disk_total = round(disk.total / 2**30,2) # GiB. disk_used = round(disk.used / 2**30,2) disk_free = round(disk.free / 2**30,2) disk_percent_used = disk.percent response['Disk'] = str(disk_free) + 'GB free / ' + str(disk_total) + 'GB total ( ' + str(disk_percent_used) + '% )' conn.send(json.dumps({"errcode": "0", "data": response}).encode()) elif (cmd == 'system.cmd'): shell = payload['shell'] Log.i('API',"Executing shell cmd %s"%shell) #res = str(check_output(shell.split(" ") )) res = subprocess.Popen(shell, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=10,shell=True, cwd=os.path.dirname(os.path.realpath(__file__))+"/../" ) stdout,stderr = res.communicate() Log.i('API/',"Executing shell cmd res %s"%stdout) res = stdout.decode('utf-8') resLo = res.lower() if ("error" in resLo or "not exists" in resLo or "forbidden" in resLo or "not allow" in resLo or "failed" in resLo): conn.send(json.dumps({"errcode": "2006", "msg": res}).encode()) else: conn.send(json.dumps({"errcode": "0", "data": res}).encode()) else: conn.send(json.dumps({"errcode": "2005", "data": {'cmd':cmd}}).encode()) except socket.timeout: try: if i == 5: i = 0 conn.send("\n") i+=1 except: break except socket.error as e: try: if i == 25: i = 0 conn.send(" ") i+=1 except: break except ValueError as e: Log.e('API/ValueError',"While E: %s"%e) except: conn.send(json.dumps({"errcode": "2003", "msg": "Error proceeding request"}).encode()) Log.e('API/ValueError',"During API request execution fail") except socket.error as e: Log.e('API/ValueError'," Closing driver: %s"% e) except ValueError as e: Log.e('API/ValueError'," Closing driver: %s"% e) conn.close() Log.i('API/',"API client disconnected: " + addr[0] + ":" + str(addr[1]))