EquipmentManagerV3.py 76 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641
  1. import base64
  2. import json
  3. import logging
  4. import re
  5. import threading
  6. import time
  7. import oss2
  8. import requests
  9. from django.db import transaction
  10. from django.db.models import Q, Max
  11. from django.views.generic.base import View
  12. from Ansjer.config import CONFIG_INFO, CONFIG_US
  13. from Controller.CheckUserData import RandomStr
  14. from Controller.DeviceConfirmRegion import Device_Region
  15. from Controller.SensorGateway.EquipmentFamilyController import EquipmentFamilyView
  16. from Controller.UnicomCombo.UnicomComboController import UnicomComboView
  17. from Controller.UnicomCombo.WXTechController import WXTechControllerView
  18. from Controller.UserDevice.DeviceVersionInfoController import DeviceVersionInfoView
  19. from Model.models import Device_Info, UID_Bucket, UID_Preview, UidSetModel, UidChannelSetModel, \
  20. Device_User, iotdeviceInfoModel, UIDCompanySerialModel, UnicomDeviceInfo, CountryModel, \
  21. DeviceCloudPhotoInfo, UidPushModel, ExperienceContextModel, LogModel, UserAudioVideoPush, UIDModel
  22. from Object.RedisObject import RedisObject
  23. from Object.ResponseObject import ResponseObject
  24. from Object.TokenObject import TokenObject
  25. from Service.CommonService import CommonService
  26. from Service.EquipmentInfoService import EquipmentInfoService
  27. from Service.ModelService import ModelService
  28. from Service.UserDeviceService import UserDeviceService
  29. from django.conf import settings
  30. ALICLOUD_AK = settings.ALICLOUD_AK
  31. ALICLOUD_SK = settings.ALICLOUD_SK
  32. LOGGER = logging.getLogger('info')
  33. class EquipmentManagerV3(View):
  34. def get(self, request, *args, **kwargs):
  35. request.encoding = 'utf-8'
  36. operation = kwargs.get('operation')
  37. return self.validation(request.GET, request, operation)
  38. def post(self, request, *args, **kwargs):
  39. request.encoding = 'utf-8'
  40. operation = kwargs.get('operation')
  41. return self.validation(request.POST, request, operation)
  42. def validation(self, request_dict, request, operation):
  43. response = ResponseObject()
  44. if operation == 'notLoginMainUserDevice':
  45. return self.not_login_do_mainUserDevice(request_dict, response)
  46. elif operation == 'notLoginMainDelDevice':
  47. return self.test_tool_del_device(request_dict, response)
  48. elif operation == 'changeDevicePassword':
  49. return self.change_device_password(request_dict, response)
  50. elif operation == 'modifyChannelName':
  51. return self.do_modify_channel_name(request_dict, response)
  52. elif operation == 'updateLinkedChannel':
  53. return self.update_linked_channel(request_dict, response)
  54. token = request_dict.get('token', None)
  55. tko = TokenObject(token)
  56. if tko.code != 0:
  57. return response.json(tko.code)
  58. response.lang = tko.lang
  59. userID = tko.userID
  60. # 手机端添加设备,查询,修改
  61. if operation == 'add':
  62. return self.do_add(userID, request_dict, response, request)
  63. if operation == 'batchAdd':
  64. return self.do_batch_add(userID, request_dict, response, request)
  65. elif operation == 'query':
  66. return self.do_query(userID, request_dict, response)
  67. elif operation == 'modify':
  68. return self.do_modify(userID, request_dict, response, request)
  69. elif operation == 'fuzzyQuery':
  70. return self.do_fuzzy_query(userID, request_dict, response)
  71. elif operation == 'mainUserDevice':
  72. return self.do_mainUserDevice(request_dict, response, userID)
  73. elif operation == 'getDeviceFeatures':
  74. return self.do_get_device_features(request_dict, response)
  75. elif operation == 'deviceRouse':
  76. return self.device_rouse(request_dict, response)
  77. elif operation == 'saveButtonUser':
  78. return self.save_button_user(request_dict, response)
  79. elif operation == 'getButtonUser':
  80. return self.get_button_user(request_dict, response)
  81. elif operation == 'verifyCode':
  82. return self.verify_code(request_dict, response)
  83. elif operation == 'viewDevicePassword':
  84. return self.view_device_password(request_dict, response)
  85. elif operation == 'editSortOrder':
  86. return self.edit_sort_order(userID, request_dict, response)
  87. elif operation == 'getDeviceListByUserId': # 根据用户id获取设备UID、设备名称列表
  88. return self.get_device_list_by_user_id(userID, response)
  89. elif operation == 'getDeviceDetailByUid': # 根据用户id获取设备详情
  90. return self.get_device_detail_by_uid(userID, request_dict, response)
  91. else:
  92. return response.json(414)
  93. @classmethod
  94. def device_rouse(cls, request_dict, response):
  95. """
  96. 设备唤醒
  97. """
  98. serial_number = request_dict.get('serialNumber', None)
  99. if not serial_number:
  100. return response.json(444)
  101. try:
  102. # 主题名称
  103. topic_name = f'/wakeup/{serial_number}_0'
  104. # 发布消息内容
  105. msg = {'payload': 'A'}
  106. result = CommonService.req_publish_mqtt_msg(serial_number, topic_name, msg)
  107. if not result:
  108. return response.json(10044)
  109. return response.json(0)
  110. except Exception as e:
  111. LOGGER.info('****设备唤醒发布消息异常:{},{}'.format(serial_number, repr(e)))
  112. return response.json(500, repr(e))
  113. def do_add(self, userID, request_dict, response, request):
  114. UID = request_dict.get('UID', None)
  115. NickName = request_dict.get('NickName', None)
  116. View_Account = request_dict.get('View_Account', None)
  117. View_Password = request_dict.get('View_Password', '')
  118. encrypt_pass = View_Password
  119. Type = request_dict.get('Type', None)
  120. ChannelIndex = request_dict.get('ChannelIndex', None)
  121. version = request_dict.get('version', '')
  122. isCheckMainUser = request_dict.get('isCheckMainUser', None)
  123. family_id = request_dict.get('familyId', None)
  124. room_id = request_dict.get('roomId', None)
  125. m_code = request_dict.get('m_code', None)
  126. appBundleId = request_dict.get('appBundleId', None)
  127. app_type = request_dict.get('app_type', None)
  128. push_type = request_dict.get('push_type', None)
  129. token_val = request_dict.get('token_val', None)
  130. jg_token_val = request_dict.get('jg_token_val', '')
  131. lang = request_dict.get('lang', 'en')
  132. tz = request_dict.get('tz', '0')
  133. if not NickName:
  134. NickName = UID[:6]
  135. if not all([UID, NickName, View_Account, Type, ChannelIndex]): # Type和ChannelIndex可能为0
  136. return response.json(444, {'param': 'UID, NickName, View_Account, Type, ChannelIndex'})
  137. if tz == '':
  138. tz = 0
  139. else:
  140. tz = tz.replace("GMT", "")
  141. Type = int(Type)
  142. ChannelIndex = int(ChannelIndex)
  143. re_uid = re.compile(r'^[A-Za-z0-9]{14,20}$')
  144. if not re_uid.match(UID):
  145. return response.json(444, {'param': 'UID'})
  146. device_info_qs = Device_Info.objects.filter(UID=UID, userID_id=userID)
  147. if device_info_qs:
  148. # 判断设备是否已存在
  149. if device_info_qs[0].isExist == 1:
  150. return response.json(174)
  151. else:
  152. device_info_qs.delete()
  153. dvr_type_list = [1, 2, 3, 4, 300, 10001]
  154. View_Password = '' if Type in dvr_type_list else 'admin'
  155. id = CommonService.getUserID(getUser=False)
  156. device_user_qs = Device_User.objects.filter(userID=userID).values('username')
  157. if not device_user_qs.exists():
  158. return response.json(173)
  159. uid_status = UIDModel.objects.filter(uid=UID).values('status').first()
  160. if uid_status and uid_status['status'] == 0:
  161. return response.json(10076)
  162. userName = device_user_qs[0]['username']
  163. main_exist = Device_Info.objects.filter(UID=UID)
  164. main_exist = main_exist.filter(~Q(vodPrimaryUserID='')).values('vodPrimaryUserID', 'vodPrimaryMaster')
  165. vodPrimaryUserID = userID
  166. vodPrimaryMaster = userName
  167. primaryUserID = ''
  168. primaryMaster = ''
  169. isShare = False
  170. is_bind = Device_Info.objects.filter(UID=UID, isShare=False).values('userID__userID', 'primaryUserID',
  171. 'primaryMaster')
  172. if main_exist.exists():
  173. vodPrimaryUserID = main_exist[0]['vodPrimaryUserID']
  174. vodPrimaryMaster = main_exist[0]['vodPrimaryMaster']
  175. if is_bind.exists():
  176. primaryUserID = is_bind[0]['primaryUserID']
  177. primaryMaster = is_bind[0]['primaryMaster']
  178. isShare = True
  179. isusermain = False
  180. if (vodPrimaryUserID != userID and vodPrimaryUserID != '') or (primaryUserID != userID and primaryUserID != ''):
  181. isusermain = True
  182. # 判断是否有已绑定用户
  183. if isCheckMainUser == '1' and isusermain:
  184. res = {
  185. 'id': id,
  186. 'userID': userID,
  187. 'NickName': NickName,
  188. 'UID': UID,
  189. 'View_Account': View_Account,
  190. 'View_Password': View_Password,
  191. 'ChannelIndex': ChannelIndex,
  192. 'Type': Type,
  193. 'isShare': isShare,
  194. 'primaryUserID': primaryUserID,
  195. 'primaryMaster': primaryMaster,
  196. 'vodPrimaryUserID': vodPrimaryUserID,
  197. 'vodPrimaryMaster': vodPrimaryMaster,
  198. 'data_joined': '',
  199. 'version': version,
  200. 'isVod': 0,
  201. 'isExist': 1,
  202. 'userID__userEmail': ''
  203. }
  204. res['vod'] = [
  205. {
  206. "status": 1,
  207. "channel": ChannelIndex,
  208. "endTime": '',
  209. "bucket__content": '',
  210. "uid": UID
  211. }
  212. ]
  213. res['isMainUserExists'] = 1
  214. LOGGER.info('add设备已绑定其他用户uid:{} type:{} 主:{} Now:{} nickName:{}'
  215. .format(UID, Type, vodPrimaryUserID, userID, NickName))
  216. return response.json(0, res)
  217. # 日志数据
  218. username = CommonService.get_username(userID)
  219. nowTime = int(time.time())
  220. ip = CommonService.get_ip_address(request)
  221. content = json.loads(json.dumps(request_dict))
  222. log = {
  223. 'ip': ip,
  224. 'user_id': 1,
  225. 'status': 200,
  226. 'time': nowTime,
  227. 'content': json.dumps(content),
  228. 'url': 'v3/equipment/add',
  229. 'operation': '{}添加{}成功'.format(username, UID)
  230. }
  231. try:
  232. with transaction.atomic():
  233. # 判断是否有用户绑定
  234. us_qs = UidSetModel.objects.filter(uid=UID)
  235. if us_qs.exists():
  236. us_qs.update(nickname=NickName, device_type=Type)
  237. UidSet_id = us_qs.first().id
  238. else:
  239. ipInfo = CommonService.getIpIpInfo(ip, 'CN')
  240. country_qs = CountryModel.objects.filter(country_code=ipInfo['country_code']).values('id')
  241. country = country_qs.exists() if country_qs[0]['id'] else 0
  242. region_id = Device_Region().get_device_region(ip)
  243. region_alexa = 'CN' if region_id == 1 else 'ALL'
  244. uid_set_create_dict = {
  245. 'uid': UID,
  246. 'addTime': nowTime,
  247. 'updTime': nowTime,
  248. 'ip': ip,
  249. 'channel': ChannelIndex,
  250. 'nickname': NickName,
  251. 'version': version,
  252. 'region_alexa': region_alexa,
  253. 'device_type': Type,
  254. 'tb_country': country
  255. }
  256. UidSet = UidSetModel.objects.create(**uid_set_create_dict)
  257. UidSet_id = UidSet.id
  258. if all([token_val, m_code, appBundleId, app_type]):
  259. uid_push_qs = UidPushModel.objects.filter(userID_id=userID, m_code=m_code, uid_set__uid=UID)
  260. if uid_push_qs.exists():
  261. uid_push_update_dict = {
  262. 'appBundleId': appBundleId,
  263. 'app_type': app_type,
  264. 'push_type': push_type,
  265. 'token_val': token_val,
  266. 'jg_token_val': jg_token_val,
  267. 'updTime': nowTime,
  268. 'lang': lang,
  269. 'tz': tz
  270. }
  271. uid_push_qs.update(**uid_push_update_dict)
  272. else:
  273. uid_push_create_dict = {
  274. 'uid_set_id': UidSet_id,
  275. 'userID_id': userID,
  276. 'appBundleId': appBundleId,
  277. 'app_type': app_type,
  278. 'push_type': push_type,
  279. 'token_val': token_val,
  280. 'jg_token_val': jg_token_val,
  281. 'm_code': m_code,
  282. 'addTime': nowTime,
  283. 'updTime': nowTime,
  284. 'lang': lang,
  285. 'tz': tz
  286. }
  287. # 绑定设备推送
  288. UidPushModel.objects.create(**uid_push_create_dict)
  289. # 查询uid_channel表有无该uid的数据
  290. uid_channel_set = UidChannelSetModel.objects.filter(uid_id=UidSet_id)
  291. if not uid_channel_set.exists():
  292. # 多通道设备设置通道名
  293. if Type in dvr_type_list:
  294. UidChannelSet_bulk = []
  295. for i in range(1, ChannelIndex + 1):
  296. channel_name = 'Channel ' + str(i) # Channel 1,Channel 2...
  297. UidChannelSet = UidChannelSetModel(uid_id=UidSet_id, channel=i, channel_name=channel_name)
  298. UidChannelSet_bulk.append(UidChannelSet)
  299. UidChannelSetModel.objects.bulk_create(UidChannelSet_bulk)
  300. # 获取当前用户下最大 sort_order
  301. max_sort_order = Device_Info.objects.filter(userID_id=userID).aggregate(
  302. Max('sort_order'))['sort_order__max'] or 0
  303. userDevice = Device_Info(id=id, userID_id=userID, UID=UID, NickName=NickName, View_Account=View_Account,
  304. View_Password=View_Password, Type=Type, ChannelIndex=ChannelIndex,
  305. version=version,
  306. vodPrimaryUserID=vodPrimaryUserID, vodPrimaryMaster=vodPrimaryMaster,
  307. sort_order=max_sort_order + 1)
  308. userDevice.save()
  309. # 保存用户推送按钮信息
  310. button_qs = UserAudioVideoPush.objects.filter(uid=UID)
  311. if button_qs.exists():
  312. button_qs.update(buttonUser1=userID, buttonUser2=userID)
  313. else:
  314. UserAudioVideoPush.objects.create(uid=UID, buttonUser1=userID, buttonUser2=userID,
  315. created_time=nowTime, updated_time=nowTime)
  316. # 添加到家庭房间
  317. if family_id:
  318. EquipmentFamilyView.family_room_device_save(family_id, room_id, userDevice.id, Type)
  319. uid_serial_qs = UIDCompanySerialModel.objects.filter(uid__uid=UID)
  320. if uid_serial_qs.exists():
  321. uid_serial = uid_serial_qs[0]
  322. serial_number = uid_serial.company_serial.serial_number + uid_serial.company_serial.company.mark
  323. Device_Info.objects.filter(UID=UID).update(vodPrimaryUserID=vodPrimaryUserID,
  324. vodPrimaryMaster=vodPrimaryMaster,
  325. serial_number=serial_number)
  326. self.unicom_user_info_save(userID, serial_number)
  327. else:
  328. Device_Info.objects.filter(UID=UID).update(vodPrimaryUserID=vodPrimaryUserID,
  329. vodPrimaryMaster=vodPrimaryMaster)
  330. if not us_qs.exists():
  331. us_qs = UidSetModel.objects.filter(uid=UID)
  332. if us_qs.exists() and us_qs[0].is_alexa == 1:
  333. if us_qs[0].channel > 1:
  334. data_list = []
  335. uid_channel_set_qs = UidChannelSetModel.objects.filter(uid_id=us_qs[0].id). \
  336. values('channel', 'channel_name')
  337. if uid_channel_set_qs.exists():
  338. # 多通道设备名为 UidChannelSetModel 的 channel_name
  339. for uid_channel_set in uid_channel_set_qs:
  340. data_list.append(
  341. {'userID': userID, 'UID': UID, 'uid_nick': uid_channel_set['channel_name'],
  342. 'channel': uid_channel_set['channel'], 'password': encrypt_pass})
  343. else:
  344. data_list = [{'userID': userID, 'UID': UID, 'uid_nick': NickName, 'password': encrypt_pass}]
  345. # 请求Alexa服务器更新事件网关
  346. CommonService.update_alexa_events(data_list)
  347. # 记录添加日志
  348. LogModel.objects.create(**log)
  349. except Exception as e:
  350. # 记录添加失败日志
  351. error_msg = 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e))
  352. operation = '{}添加{}失败:{}'.format(username, UID, error_msg)
  353. log['operation'] = operation
  354. LogModel.objects.create(**log)
  355. return response.json(10, error_msg)
  356. else:
  357. dvqs = Device_Info.objects.filter(id=id).values('id', 'userID', 'NickName', 'UID',
  358. 'View_Account',
  359. 'View_Password', 'ChannelIndex', 'Type',
  360. 'isShare',
  361. 'primaryUserID', 'primaryMaster',
  362. 'vodPrimaryUserID', 'vodPrimaryMaster',
  363. 'userID__userEmail',
  364. 'data_joined', 'version',
  365. 'isVod', 'isExist', 'isCameraOpenCloud', 'serial_number')
  366. dvql = CommonService.qs_to_list(dvqs)
  367. ubqs = UID_Bucket.objects.filter(uid=UID). \
  368. values('bucket__content', 'status', 'channel', 'endTime', 'uid')
  369. res = dvql[0]
  370. res['vod'] = list(ubqs)
  371. iotqs = iotdeviceInfoModel.objects.filter(serial_number=dvql[0]['serial_number'])
  372. if iotqs.exists():
  373. res['iot'] = {
  374. 'endpoint': iotqs[0].endpoint,
  375. 'token_iot_number': iotqs[0].endpoint
  376. }
  377. # 存在序列号返回完整序列号
  378. if res['serial_number']:
  379. res['serial_number'] = CommonService.get_full_serial_number(UID, res['serial_number'], Type)
  380. return response.json(0, res)
  381. @classmethod
  382. def unicom_user_info_save(cls, user_id, serial_number):
  383. """
  384. 保存联通与用户信息绑定
  385. @param user_id: 用户id
  386. @param serial_number: 序列号
  387. @return: True | False
  388. """
  389. try:
  390. # 根据序列号查询联通iccid
  391. unicom_device_info_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_number, card_type=0)
  392. if not unicom_device_info_qs.exists():
  393. return False
  394. unicom_device_info_qs.update(user_id=user_id, updated_time=int(time.time()))
  395. LOGGER.info('{}更新4G用户信息成功:{}'.format(serial_number, user_id))
  396. # if unicom_device_info_qs.first().status == 1: # 已测试
  397. # # 领取4G体验套餐
  398. # res = UnicomComboView.user_activate_flow(unicom_device_info_qs[0].iccid)
  399. # logging.info('{}联通领取体验流量:{}'.format(unicom_device_info_qs[0].iccid, res))
  400. # WXTechControllerView.activate_flow_package(serial_number, 'system', user_id)
  401. # if not unicom_device_info_qs[0].user_id:
  402. # # 生成4G免费订单
  403. # UnicomComboView.experience_order_4G(unicom_device_info_qs[0].iccid,
  404. # serial_number, user_id, False)
  405. # UnicomDeviceInfo.objects.filter(iccid=unicom_device_info_qs[0].iccid) \
  406. # .update(user_id=user_id, updated_time=int(time.time()))
  407. return True
  408. except Exception as e:
  409. logging.info('创建体验4G订单异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  410. return False
  411. def do_batch_add(self, userID, request_dict, response, request):
  412. # 批量添加设备
  413. uidContent = request_dict.get('uidContent', None)
  414. family_id = request_dict.get('familyId', None)
  415. room_id = request_dict.get('roomId', None)
  416. if not uidContent:
  417. return response.json(444, {'param': 'uidContent'})
  418. try:
  419. deviceNumber = 0 # 添加成功数量
  420. add_success_flag = False # 添加成功标识
  421. exception_flag = False # 异常标识
  422. exists_flag = False # 已存在标识
  423. uid_content_list = eval(uidContent)
  424. print('uidContent: ', uid_content_list)
  425. re_uid = re.compile(r'^[A-Za-z0-9]{14,20}$')
  426. for uid_content in uid_content_list:
  427. exception_flag = False # 重置异常标识
  428. exists_flag = False # 已存在标识
  429. UID = uid_content['uid']
  430. NickName = uid_content['nickName']
  431. Type = uid_content['type']
  432. ChannelIndex = uid_content['channelIndex']
  433. version = uid_content['version']
  434. isCheckMainUser = uid_content['isCheckMainUser']
  435. View_Account = uid_content['viewAccount']
  436. encryptPassword = uid_content['encryptPassword']
  437. View_Password = self.decode_pwd(encryptPassword)
  438. if not all([UID, NickName, View_Account]): # Type和ChannelIndex可能为0
  439. return response.json(444, {'param': 'UID, NickName, View_Account'})
  440. if not re_uid.match(UID): # 检查uid长度
  441. return response.json(444, {'error uid length': UID})
  442. device_info_qs = Device_Info.objects.filter(UID=UID, userID_id=userID)
  443. if device_info_qs:
  444. # 判断设备是否已存在
  445. if device_info_qs[0].isExist == 1:
  446. exists_res = {UID: 'device already exists!'}
  447. exists_flag = True
  448. continue
  449. else:
  450. device_info_qs.delete()
  451. id = CommonService.getUserID(getUser=False)
  452. device_user_qs = Device_User.objects.filter(userID=userID).values('username')
  453. if not device_user_qs.exists():
  454. return response.json(173)
  455. userName = device_user_qs[0]['username']
  456. main_exist = Device_Info.objects.filter(UID=UID)
  457. main_exist = main_exist.filter(~Q(vodPrimaryUserID='')).values('vodPrimaryUserID', 'vodPrimaryMaster')
  458. vodPrimaryUserID = userID
  459. vodPrimaryMaster = userName
  460. primaryUserID = ''
  461. primaryMaster = ''
  462. isShare = False
  463. is_bind = Device_Info.objects.filter(UID=UID, isShare=False).values('userID__userID', 'primaryUserID',
  464. 'primaryMaster', 'Type')
  465. if main_exist.exists():
  466. vodPrimaryUserID = main_exist[0]['vodPrimaryUserID']
  467. vodPrimaryMaster = main_exist[0]['vodPrimaryMaster']
  468. if is_bind.exists():
  469. primaryUserID = is_bind[0]['primaryUserID']
  470. primaryMaster = is_bind[0]['primaryMaster']
  471. isShare = True
  472. isusermain = False
  473. if (vodPrimaryUserID != userID and vodPrimaryUserID != '') or (
  474. primaryUserID != userID and primaryUserID != ''):
  475. isusermain = True
  476. # 判断是否有已绑定用户
  477. if isCheckMainUser == 1 and isusermain:
  478. res = {
  479. 'id': id,
  480. 'userID': userID,
  481. 'NickName': NickName,
  482. 'UID': UID,
  483. 'View_Account': View_Account,
  484. 'View_Password': View_Password,
  485. 'ChannelIndex': ChannelIndex,
  486. 'Type': Type,
  487. 'isShare': isShare,
  488. 'primaryUserID': primaryUserID,
  489. 'primaryMaster': primaryMaster,
  490. 'vodPrimaryUserID': vodPrimaryUserID,
  491. 'vodPrimaryMaster': vodPrimaryMaster,
  492. 'data_joined': '',
  493. 'version': version,
  494. 'isVod': 0,
  495. 'isExist': 1,
  496. 'userID__userEmail': ''
  497. }
  498. res['vod'] = [
  499. {
  500. "status": 1,
  501. "channel": ChannelIndex,
  502. "endTime": '',
  503. "bucket__content": '',
  504. "uid": UID
  505. }
  506. ]
  507. res['isMainUserExists'] = 1
  508. continue
  509. # 判断是否有用户绑定
  510. nowTime = int(time.time())
  511. us_qs = UidSetModel.objects.filter(uid=UID)
  512. if us_qs.exists():
  513. us_qs.update(nickname=NickName)
  514. UidSet_id = us_qs.first().id
  515. else:
  516. ip = CommonService.get_ip_address(request)
  517. ipInfo = CommonService.getIpIpInfo(ip, 'CN')
  518. country_qs = CountryModel.objects.filter(country_code=ipInfo['country_code']).values('id')
  519. country = country_qs.exists() if country_qs[0]['id'] else 0
  520. region_id = Device_Region().get_device_region(ip)
  521. region_alexa = 'CN' if region_id == 1 else 'ALL'
  522. uid_set_create_dict = {
  523. 'uid': UID,
  524. 'addTime': nowTime,
  525. 'updTime': nowTime,
  526. 'ip': CommonService.get_ip_address(request_dict),
  527. 'channel': ChannelIndex,
  528. 'nickname': NickName,
  529. 'version': version,
  530. 'region_alexa': region_alexa,
  531. 'device_type': is_bind[0]['Type'] if is_bind.exists() else int(Type),
  532. 'tb_country': country
  533. }
  534. UidSet = UidSetModel.objects.create(**uid_set_create_dict)
  535. UidSet_id = UidSet.id
  536. # 查询uid_channel表有无该uid的数据
  537. uid_channel_set = UidChannelSetModel.objects.filter(uid_id=UidSet_id)
  538. if not uid_channel_set.exists():
  539. # 多通道设备设置通道名
  540. multi_channel_list = [1, 2, 3, 4, 10001]
  541. if Type in multi_channel_list:
  542. UidChannelSet_bulk = []
  543. for i in range(1, ChannelIndex + 1):
  544. channel_name = 'channel' + str(i) # channel1,channel2...
  545. UidChannelSet = UidChannelSetModel(uid_id=UidSet_id, channel=i, channel_name=channel_name)
  546. UidChannelSet_bulk.append(UidChannelSet)
  547. UidChannelSetModel.objects.bulk_create(UidChannelSet_bulk)
  548. userDevice = Device_Info(id=id, userID_id=userID, UID=UID, NickName=NickName, View_Account=View_Account,
  549. View_Password=View_Password, Type=Type, ChannelIndex=ChannelIndex,
  550. version=version,
  551. vodPrimaryUserID=vodPrimaryUserID, vodPrimaryMaster=vodPrimaryMaster)
  552. userDevice.save()
  553. # 添加到家庭房间
  554. if family_id:
  555. EquipmentFamilyView.family_room_device_save(family_id, room_id, userDevice.id, Type)
  556. uid_serial_qs = UIDCompanySerialModel.objects.filter(uid__uid=UID)
  557. if uid_serial_qs.exists():
  558. uid_serial = uid_serial_qs[0]
  559. Device_Info.objects.filter(UID=UID).update(vodPrimaryUserID=vodPrimaryUserID,
  560. vodPrimaryMaster=vodPrimaryMaster,
  561. serial_number=uid_serial.company_serial.serial_number + uid_serial.company_serial.company.mark)
  562. else:
  563. Device_Info.objects.filter(UID=UID).update(vodPrimaryUserID=vodPrimaryUserID,
  564. vodPrimaryMaster=vodPrimaryMaster)
  565. if not us_qs.exists():
  566. us_qs = UidSetModel.objects.filter(uid=UID)
  567. if us_qs.exists() and us_qs[0].is_alexa == 1:
  568. if us_qs[0].channel > 1:
  569. data_list = []
  570. uid_channel_set_qs = UidChannelSetModel.objects.filter(uid_id=us_qs[0].id). \
  571. values('channel', 'channel_name')
  572. if uid_channel_set_qs.exists():
  573. # 多通道设备名为 UidChannelSetModel 的 channel_name
  574. for uid_channel_set in uid_channel_set_qs:
  575. data_list.append(
  576. {'userID': userID, 'UID': UID, 'uid_nick': uid_channel_set['channel_name'],
  577. 'channel': uid_channel_set['channel'], 'password': encryptPassword})
  578. else:
  579. data_list = [{'userID': userID, 'UID': UID, 'uid_nick': NickName, 'password': encryptPassword}]
  580. # 请求Alexa服务器更新事件网关
  581. CommonService.update_alexa_events(data_list)
  582. dvqs = Device_Info.objects.filter(id=id).values('id', 'userID', 'NickName', 'UID',
  583. 'View_Account',
  584. 'View_Password', 'ChannelIndex', 'Type',
  585. 'isShare',
  586. 'primaryUserID', 'primaryMaster',
  587. 'vodPrimaryUserID', 'vodPrimaryMaster',
  588. 'userID__userEmail',
  589. 'data_joined', 'version',
  590. 'isVod', 'isExist', 'isCameraOpenCloud',
  591. 'serial_number')
  592. dvql = CommonService.qs_to_list(dvqs)
  593. ubqs = UID_Bucket.objects.filter(uid=UID). \
  594. values('bucket__content', 'status', 'channel', 'endTime', 'uid')
  595. success_res = dvql[0]
  596. success_res['vod'] = list(ubqs)
  597. iotqs = iotdeviceInfoModel.objects.filter(serial_number=dvql[0]['serial_number'])
  598. if iotqs.exists():
  599. success_res['iot'] = {'endpoint': iotqs[0].endpoint, 'token_iot_number': iotqs[0].endpoint}
  600. deviceNumber += 1
  601. success_res['deviceNumber'] = deviceNumber
  602. add_success_flag = True
  603. except Exception as e:
  604. LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  605. print(e)
  606. error_res = repr(e)
  607. exception_flag = True
  608. pass
  609. finally:
  610. if add_success_flag: # 有一台添加成功则返回成功
  611. return response.json(0, success_res)
  612. if exists_flag: # 全部设备已存在
  613. return response.json(174, exists_res)
  614. if exception_flag:
  615. return response.json(500, error_res)
  616. return response.json(0, res)
  617. def do_modify(self, userID, request_dict, response, request):
  618. token = request_dict.get('token', None)
  619. deviceContent = request_dict.get('content', None)
  620. id = request_dict.get('id', None)
  621. if not deviceContent or not id:
  622. return response.json(444, 'content,id')
  623. tko = TokenObject(token)
  624. response.lang = tko.lang
  625. if tko.code != 0:
  626. return response.json(tko.code)
  627. userID = tko.userID
  628. if userID is None:
  629. return response.json(309)
  630. try:
  631. deviceData = eval(deviceContent)
  632. if deviceData.__contains__('userID_id'):
  633. asy = threading.Thread(target=ModelService.update_log,
  634. args=(CommonService.get_ip_address(request), userID, 'modifyV3', deviceData, id))
  635. asy.start()
  636. return response.json(10, '110')
  637. if deviceData.__contains__('UID'):
  638. del deviceData['UID']
  639. dev_info_qs = Device_Info.objects.filter(userID_id=userID, id=id).values('UID')
  640. if not dev_info_qs.exists():
  641. return response.json(173)
  642. view_password = ''
  643. if deviceData.__contains__('View_Password'):
  644. encrypt_pwd = deviceData['View_Password']
  645. view_password = self.decode_pwd(deviceData['View_Password'])
  646. deviceData['View_Password'] = view_password
  647. # 记录修改密码日志
  648. uid = dev_info_qs[0]['UID']
  649. ip = CommonService.get_ip_address(request)
  650. content = json.loads(json.dumps(request_dict))
  651. log = {
  652. 'user_id': 2,
  653. 'status': 200,
  654. 'time': int(time.time()),
  655. 'url': 'v3/equipment/modify',
  656. 'content': json.dumps(content),
  657. 'ip': ip,
  658. 'operation': '{}修改设备密码:{}'.format(uid, view_password),
  659. }
  660. LogModel.objects.create(**log)
  661. # 更新数据
  662. dev_info_qs.update(**deviceData)
  663. except Exception as e:
  664. print(e)
  665. return response.json(177, repr(e))
  666. else:
  667. qs = Device_Info.objects.filter(userID_id=userID, id=id)
  668. res = CommonService.qs_to_dict(qs)
  669. if qs.exists():
  670. uid = qs[0].UID
  671. nickname = qs[0].NickName
  672. # 增加设备影子信息修改昵称 start
  673. us_qs = UidSetModel.objects.filter(uid=uid)
  674. if us_qs.exists():
  675. if deviceData.__contains__('NickName'):
  676. us_qs.update(nickname=nickname)
  677. else:
  678. ip = CommonService.get_ip_address(request)
  679. ipInfo = CommonService.getIpIpInfo(ip, 'CN')
  680. country_qs = CountryModel.objects.filter(country_code=ipInfo['country_code']).values('id')
  681. country = country_qs.exists() if country_qs[0]['id'] else 0
  682. ChannelIndex = qs[0].ChannelIndex
  683. nowTime = int(time.time())
  684. uid_set_create_dict = {
  685. 'uid': uid,
  686. 'addTime': nowTime,
  687. 'updTime': nowTime,
  688. 'ip': CommonService.get_ip_address(request),
  689. 'channel': ChannelIndex,
  690. 'nickname': nickname,
  691. 'device_type': qs[0].Type,
  692. 'tb_country': country,
  693. }
  694. UidSetModel.objects.create(**uid_set_create_dict)
  695. di_qs = Device_Info.objects.filter(UID=uid)
  696. di_qs.update(NickName=nickname)
  697. if deviceData is not None and deviceData.__contains__('NickName') and us_qs[0].is_alexa == 1:
  698. # 异步请求Alexa服务器更新事件网关
  699. password = encrypt_pwd if deviceData.__contains__('View_Password') else ''
  700. data_list = [{'userID': userID, 'UID': uid, 'uid_nick': nickname, 'password': password}]
  701. # 请求Alexa服务器更新事件网关
  702. CommonService.update_alexa_events(data_list)
  703. return response.json(0, res)
  704. @staticmethod
  705. def do_modify_channel_name(request_dict, response):
  706. """
  707. 修改通道名
  708. @param request_dict:
  709. @param response:
  710. @return:
  711. """
  712. uid = request_dict.get('uid', None)
  713. channel = request_dict.get('channel', None)
  714. channel_name = request_dict.get('channel_name', None)
  715. if not all([uid, channel, channel_name]):
  716. return response.json(444)
  717. try:
  718. # 更新通道名
  719. channel = int(channel) + 1
  720. uid_channel_set_qs = UidChannelSetModel.objects.filter(uid__uid=uid, channel=channel)
  721. if not uid_channel_set_qs.exists():
  722. return response.json(173)
  723. uid_channel_set_qs.update(channel_name=channel_name)
  724. return response.json(0)
  725. except Exception as e:
  726. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  727. @staticmethod
  728. def update_linked_channel(request_dict, response):
  729. """
  730. 更新连接通道
  731. @param request_dict:
  732. @param response:
  733. @return:
  734. """
  735. uid = request_dict.get('uid', None)
  736. linked_channel = request_dict.get('linked_channel', None)
  737. if not all([uid, linked_channel]):
  738. return response.json(444)
  739. try:
  740. UidSetModel.objects.filter(uid=uid).update(linked_channel=linked_channel)
  741. return response.json(0)
  742. except Exception as e:
  743. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  744. def do_query(self, userID, request_dict, response):
  745. """
  746. 首页查询设备列表
  747. @param userID: 用户id
  748. @param request_dict: 请求参数
  749. @param response: 响应结果
  750. """
  751. token = request_dict.get('token', None)
  752. page = request_dict.get('page', None)
  753. line = request_dict.get('line', None)
  754. NickName = request_dict.get('NickName', None)
  755. if not token or not page or not line:
  756. return response.json(444)
  757. page = int(page)
  758. line = int(line)
  759. uid = request_dict.get('uid', None)
  760. tko = TokenObject(token)
  761. response.lang = tko.lang
  762. if page <= 0:
  763. return response.json(0)
  764. if tko.code != 0:
  765. return response.json(tko.code)
  766. userID = tko.userID
  767. UserDeviceService.init_device_sort_order(userID)
  768. group_id = int(request_dict.get('groupId', 0))
  769. # 查询设备列表以及设备uid集合
  770. dv_list, uid_list = UserDeviceService.query_device_list(userID, uid, NickName, page, line, group_id)
  771. ub_qs = UserDeviceService.query_device_uid_bucket(uid_list) # 根据uid集合查询云存套餐
  772. up_qs = UserDeviceService.query_device_preview(uid_list) # 根据uid集合查询设备预览图
  773. auth = oss2.Auth(ALICLOUD_AK, ALICLOUD_SK)
  774. bucket = oss2.Bucket(auth, 'oss-cn-hongkong.aliyuncs.com', 'statres')
  775. nowTime = int(time.time())
  776. data = []
  777. uv_dict = UserDeviceService.query_device_channel(uid_list) # 查询设备uid通道配置属性
  778. # 遍历设备列表,查询设备关联数据详情
  779. for p in dv_list:
  780. p['UID'] = p['UID'].replace('\n', '').replace('\r', '')
  781. p_uid = p['UID'].upper()
  782. UserDeviceService.get_sim_by_serial_number(p) # 获取SIM卡属性
  783. p['cloudPhoto'] = self.get_cloud_photo_status(p['UID'])
  784. # 获取云存使用状态
  785. p['vod_use_status'] = self.get_vod_use_status(p_uid, nowTime)
  786. # 获取iot_deviceInfo表的endpoint和token_iot_number
  787. p['iot'] = []
  788. if p['serial_number']: # 存在序列号根据序列号查询
  789. iotdeviceInfo_qs = iotdeviceInfoModel.objects.filter(serial_number=p['serial_number'][0:6])
  790. else: # 根据uid查询
  791. iotdeviceInfo_qs = iotdeviceInfoModel.objects.filter(uid=p_uid)
  792. if iotdeviceInfo_qs.exists():
  793. iotdeviceInfo = iotdeviceInfo_qs.values('endpoint', 'token_iot_number')
  794. p['iot'].append({
  795. 'endpoint': iotdeviceInfo[0]['endpoint'],
  796. 'token_iot_number': iotdeviceInfo[0]['token_iot_number']
  797. })
  798. p['vod'] = []
  799. for dm in ub_qs:
  800. if p_uid == dm['uid']:
  801. if dm['endTime'] > nowTime:
  802. p['vod'].append(dm)
  803. p['preview'] = []
  804. for up in up_qs:
  805. if p_uid == up['uid']:
  806. obj = 'uid_preview/{uid}/channel_{channel}.png'.format(uid=up['uid'], channel=up['channel'])
  807. img_sign = bucket.sign_url('GET', obj, 300)
  808. p['preview'].append(img_sign)
  809. UserDeviceService.get_uid_info(p, p_uid) # 获取uid初始化信息
  810. if p_uid in uv_dict:
  811. # 获取设备信息DTO
  812. UserDeviceService.get_device_info_dto(p, p_uid, uv_dict, userID)
  813. else:
  814. # 设备版本号
  815. p['uid_version'] = ''
  816. p['ucode'] = ''
  817. p['View_Password'] = self.encrypt_pwd(p['View_Password'])
  818. # 判断设备是否支持4G和查询移动侦测状态
  819. uid_set_qs = UidSetModel.objects.filter(uid=p['UID']).values('detect_status', 'ucode', 'version')
  820. if uid_set_qs.exists():
  821. uid_set_qs = uid_set_qs.first()
  822. p['has_4g_cloud'] = self.get_device_is_4G(uid_set_qs['ucode'], uid_set_qs['version'])
  823. if p['has_4g_cloud'] == 1:
  824. p['isCameraOpenCloud'] = 1
  825. p['NotificationMode'] = uid_set_qs['detect_status']
  826. data.append(p)
  827. result = data
  828. return response.json(0, result)
  829. @staticmethod
  830. def get_device_is_4G(ucode, ver):
  831. try:
  832. if not all([ucode, ver]):
  833. return 0
  834. ver = ver.replace('V', '')
  835. d_ver = DeviceVersionInfoView.cache_device_version_info(ucode, ver)
  836. if d_ver:
  837. return 1 if d_ver['has_4g_cloud'] == 1 else 0
  838. return 0
  839. except Exception as e:
  840. LOGGER.error(f'{ucode}首页返回配置信息异常{repr(e)}')
  841. return 0
  842. @staticmethod
  843. def get_vod_use_status(uid, now_time):
  844. """
  845. 根据UID获取云存使用状态
  846. @param uid: 设备uid
  847. @param now_time: 现在时间戳
  848. @return: 0:未体验;1:使用中;2:已过期
  849. """
  850. experience_context_qs = ExperienceContextModel.objects.filter(uid=uid, experience_type=0)
  851. if not experience_context_qs.exists():
  852. return 0
  853. uid_bucket_qs = UID_Bucket.objects.filter(uid=uid, endTime__gt=now_time, use_status=1)
  854. if uid_bucket_qs.exists():
  855. return 1
  856. else:
  857. return 2
  858. @staticmethod
  859. def get_cloud_photo_status(uid):
  860. """
  861. 根据UID获取云相册开关状态
  862. @param uid: 设备uid
  863. @return: 0 or 1
  864. """
  865. cloud_photo_qs = DeviceCloudPhotoInfo.objects.filter(uid=uid).values('status')
  866. if not cloud_photo_qs.exists():
  867. return 0
  868. return cloud_photo_qs[0]['status']
  869. def do_fuzzy_query(self, userID, request_dict, response):
  870. fuzzy = request_dict.get('fuzzy', None)
  871. page = request_dict.get('page', None)
  872. line = request_dict.get('line', None)
  873. if not all([page, line]):
  874. return response.json(444)
  875. page = int(page)
  876. line = int(line)
  877. try:
  878. device_qs = Device_Info.objects.filter(userID=userID)
  879. device_qs = device_qs.filter(~Q(isExist=2))
  880. if not device_qs.exists():
  881. return response.json(0, [])
  882. if fuzzy:
  883. device_qs = device_qs.filter(Q(UID__icontains=fuzzy) | Q(NickName__icontains=fuzzy))
  884. device_qs = device_qs.values('id', 'userID', 'NickName', 'UID', 'View_Account',
  885. 'View_Password', 'ChannelIndex', 'Type', 'isShare',
  886. 'primaryUserID', 'primaryMaster', 'data_joined', 'vodPrimaryUserID',
  887. 'vodPrimaryMaster', 'userID__userEmail',
  888. 'version', 'isVod', 'isExist', 'NotificationMode', 'isCameraOpenCloud',
  889. 'serial_number')
  890. dvls = CommonService.qs_to_list(device_qs)
  891. uid_list = []
  892. for dvl in dvls:
  893. uid_list.append(dvl['UID'])
  894. ubqs = UID_Bucket.objects.filter(uid__in=uid_list). \
  895. values('bucket__content', 'status', 'channel', 'endTime', 'uid')
  896. upqs = UID_Preview.objects.filter(uid__in=uid_list).order_by('channel').values('id', 'uid', 'channel')
  897. auth = oss2.Auth(ALICLOUD_AK, ALICLOUD_SK)
  898. bucket = oss2.Bucket(auth, 'oss-cn-hongkong.aliyuncs.com', 'statres')
  899. nowTime = int(time.time())
  900. data = []
  901. # 设备拓展信息表
  902. us_qs = UidSetModel.objects.filter(uid__in=uid_list).values('id', 'uid', 'version', 'nickname', 'ucode',
  903. 'detect_status', 'detect_group',
  904. 'detect_interval',
  905. 'region_alexa', 'is_alexa', 'deviceModel',
  906. 'TimeZone', 'TimeStatus', 'SpaceUsable',
  907. 'SpaceSum', 'MirrorType', 'RecordType',
  908. 'OutdoorModel', 'WIFIName', 'isDetector',
  909. 'DetectorRank')
  910. uv_dict = {}
  911. for us in us_qs:
  912. uv_dict[us['uid']] = {
  913. 'version': us['version'],
  914. 'nickname': us['nickname'],
  915. 'ucode': us['ucode'],
  916. 'detect_interval': us['detect_interval'],
  917. 'detect_group': us['detect_group'],
  918. 'detect_status': us['detect_status'],
  919. 'region_alexa': us['region_alexa'],
  920. 'is_alexa': us['is_alexa'],
  921. 'deviceModel': us['deviceModel'],
  922. 'TimeZone': us['TimeZone'],
  923. 'TimeStatus': us['TimeStatus'],
  924. 'SpaceUsable': us['SpaceUsable'],
  925. 'SpaceSum': us['SpaceSum'],
  926. 'MirrorType': us['MirrorType'],
  927. 'RecordType': us['RecordType'],
  928. 'OutdoorModel': us['OutdoorModel'],
  929. 'WIFIName': us['WIFIName'],
  930. 'isDetector': us['isDetector'],
  931. 'DetectorRank': us['DetectorRank']
  932. }
  933. # 从uid_channel里面取出通道配置信息
  934. ucs_qs = UidChannelSetModel.objects.filter(uid__id=us['id']).values()
  935. channels = []
  936. for ucs in ucs_qs:
  937. channel = {
  938. 'channel': ucs['channel'],
  939. 'channel_name': ucs['channel_name'],
  940. 'pir_audio': ucs['pir_audio'],
  941. 'mic_audio': ucs['mic_audio'],
  942. 'battery_status': ucs['battery_status'],
  943. 'battery_level': ucs['battery_level'],
  944. 'sleep_status': ucs['sleep_status'],
  945. 'sleep_time': ucs['sleep_time'],
  946. 'light_night_model': ucs['light_night_model'],
  947. 'light_alarm_type': ucs['light_alarm_type'],
  948. 'light_alarm_level': ucs['light_alarm_level'],
  949. 'light_alarm_man_en': ucs['light_alarm_man_en'],
  950. 'light_alarm_vol': ucs['light_alarm_vol'],
  951. 'light_long_light': ucs['light_long_light']
  952. }
  953. channels.append(channel)
  954. uv_dict[us['uid']]['channels'] = channels
  955. for p in dvls:
  956. # 获取iot_deviceInfo表的endpoint和token_iot_number
  957. p['iot'] = []
  958. if p['serial_number']: # 存在序列号根据序列号查询
  959. # 摄像头设备返回完整序列号
  960. if p['UID'] != p['serial_number']:
  961. p['serial_number'] = CommonService.get_full_serial_number(p['UID'], p['serial_number'],
  962. p['Type'])
  963. iotdeviceInfo_qs = iotdeviceInfoModel.objects.filter(serial_number=p['serial_number'][0:6])
  964. else: # 根据uid查询
  965. iotdeviceInfo_qs = iotdeviceInfoModel.objects.filter(uid=p['UID'])
  966. if iotdeviceInfo_qs.exists():
  967. iotdeviceInfo = iotdeviceInfo_qs.values('endpoint', 'token_iot_number')
  968. p['iot'].append({
  969. 'endpoint': iotdeviceInfo[0]['endpoint'],
  970. 'token_iot_number': iotdeviceInfo[0]['token_iot_number']
  971. })
  972. p['vod'] = []
  973. for dm in ubqs:
  974. if p['UID'] == dm['uid']:
  975. if dm['endTime'] > nowTime:
  976. p['vod'].append(dm)
  977. p['preview'] = []
  978. for up in upqs:
  979. if p['UID'] == up['uid']:
  980. obj = 'uid_preview/{uid}/channel_{channel}.png'.format(uid=up['uid'], channel=up['channel'])
  981. img_sign = bucket.sign_url('GET', obj, 300)
  982. p['preview'].append(img_sign)
  983. p_uid = p['UID']
  984. if p_uid in uv_dict:
  985. # 设备版本号
  986. p['uid_version'] = uv_dict[p_uid]['version']
  987. p['ucode'] = uv_dict[p_uid]['ucode']
  988. p['detect_interval'] = uv_dict[p_uid]['detect_interval']
  989. p['detect_status'] = uv_dict[p_uid]['detect_status']
  990. p['detect_group'] = uv_dict[p_uid]['detect_group']
  991. p['region_alexa'] = uv_dict[p_uid]['region_alexa']
  992. p['is_alexa'] = uv_dict[p_uid]['is_alexa']
  993. p['deviceModel'] = uv_dict[p_uid]['deviceModel']
  994. p['TimeZone'] = uv_dict[p_uid]['TimeZone']
  995. p['TimeStatus'] = uv_dict[p_uid]['TimeStatus']
  996. p['SpaceUsable'] = uv_dict[p_uid]['SpaceUsable']
  997. p['SpaceSum'] = uv_dict[p_uid]['SpaceSum']
  998. p['MirrorType'] = uv_dict[p_uid]['MirrorType']
  999. p['RecordType'] = uv_dict[p_uid]['RecordType']
  1000. p['OutdoorModel'] = uv_dict[p_uid]['OutdoorModel']
  1001. p['WIFIName'] = uv_dict[p_uid]['WIFIName']
  1002. p['isDetector'] = uv_dict[p_uid]['isDetector']
  1003. p['DetectorRank'] = uv_dict[p_uid]['DetectorRank']
  1004. p['channels'] = uv_dict[p_uid]['channels']
  1005. # 设备昵称 调用影子信息昵称,先阶段不可
  1006. if uv_dict[p_uid]['nickname']:
  1007. p['NickName'] = uv_dict[p_uid]['nickname']
  1008. else:
  1009. # 设备版本号
  1010. p['uid_version'] = ''
  1011. p['ucode'] = ''
  1012. data.append(p)
  1013. items = []
  1014. for index, item in enumerate(data):
  1015. if (page - 1) * line <= index:
  1016. if index < page * line:
  1017. # 加密
  1018. item['View_Password'] = self.encrypt_pwd(item['View_Password'])
  1019. items.append(item)
  1020. return response.json(0, items)
  1021. except Exception as e:
  1022. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  1023. # 加密
  1024. def encrypt_pwd(self, userPwd):
  1025. for i in range(1, 4):
  1026. if i == 1:
  1027. userPwd = RandomStr(3, False) + userPwd + RandomStr(3, False)
  1028. userPwd = base64.b64encode(str(userPwd).encode("utf-8")).decode('utf8')
  1029. if i == 2:
  1030. userPwd = RandomStr(2, False) + str(userPwd) + RandomStr(2, False)
  1031. userPwd = base64.b64encode(str(userPwd).encode("utf-8")).decode('utf8')
  1032. if i == 3:
  1033. userPwd = RandomStr(1, False) + str(userPwd) + RandomStr(1, False)
  1034. userPwd = base64.b64encode(str(userPwd).encode("utf-8")).decode('utf8')
  1035. return userPwd
  1036. # 解密
  1037. def decode_pwd(self, password):
  1038. for i in range(1, 4):
  1039. if i == 1:
  1040. # 第一次先解密
  1041. password = base64.b64decode(password)
  1042. password = password.decode('utf-8')
  1043. # 截去第一位,最后一位
  1044. password = password[1:-1]
  1045. if i == 2:
  1046. # 第2次先解密
  1047. password = base64.b64decode(password)
  1048. password = password.decode('utf-8')
  1049. # 去前2位,后2位
  1050. password = password[2:-2]
  1051. if i == 3:
  1052. # 第3次先解密
  1053. password = base64.b64decode(password)
  1054. password = password.decode('utf-8')
  1055. # 去前3位,后3位
  1056. password = password[3:-3]
  1057. return password
  1058. @staticmethod
  1059. def do_mainUserDevice(request_dict, response, user_id):
  1060. """
  1061. 根据UID或序列号获取云存主用户信息
  1062. """
  1063. try:
  1064. UID = request_dict.get('UID')
  1065. serial_number = request_dict.get('serial_number')
  1066. if UID:
  1067. dvq = Device_Info.objects.filter(UID=UID)
  1068. elif serial_number:
  1069. serial_number = serial_number[:9]
  1070. uid = CommonService.get_uid_by_serial_number(serial_number)
  1071. if serial_number == uid: # 没查到绑定对应的UID
  1072. dvq = Device_Info.objects.filter(serial_number=serial_number)
  1073. else: # 根据序列号查到了对应的UID
  1074. dvq = Device_Info.objects.filter(UID=uid)
  1075. else:
  1076. return response.json(444)
  1077. dvq = dvq.filter(~Q(vodPrimaryUserID='')).values('vodPrimaryUserID')
  1078. if not dvq.exists():
  1079. return response.json(0, [])
  1080. qs = Device_User.objects.filter(userID=dvq[0]['vodPrimaryUserID']) \
  1081. .values('userID', 'NickName', 'username', 'userEmail', 'phone')
  1082. if not qs.exists():
  1083. return response.json(0, [])
  1084. nickname = qs[0]['username']
  1085. phone = qs[0]['phone']
  1086. username = qs[0]['username']
  1087. sys_user_id = qs[0]['userID']
  1088. qs = CommonService.qs_to_list(qs)
  1089. if nickname == '':
  1090. qs[0]['NickName'] = username
  1091. if phone == '':
  1092. qs[0]['phone'] = nickname
  1093. # 查询主用户并且返回主用户是否是当前账户标识
  1094. qs[0]['isOwnUser'] = sys_user_id and user_id and sys_user_id == user_id
  1095. return response.json(0, qs)
  1096. except Exception as e:
  1097. LOGGER.info('异常详情,userID:{}, errLine:{}, errMsg:{}'.format(user_id, e.__traceback__.tb_lineno, repr(e)))
  1098. return response.json(500)
  1099. def not_login_do_mainUserDevice(self, request_dict, response):
  1100. UID = request_dict.get('UID')
  1101. token = request_dict.get('token', None)
  1102. time_stamp = request_dict.get('time_stamp', None)
  1103. if not all([token, time_stamp]):
  1104. return response.json(444)
  1105. # 时间戳token校验
  1106. if not CommonService.check_time_stamp_token(token, time_stamp):
  1107. return response.json(13)
  1108. dvq = Device_Info.objects.filter(UID=UID)
  1109. dvq = dvq.filter(~Q(vodPrimaryUserID='')).values('vodPrimaryUserID')
  1110. qs = {}
  1111. if dvq.exists():
  1112. qs = Device_User.objects.filter(userID=dvq[0]['vodPrimaryUserID']).values('userID', 'NickName', 'username',
  1113. 'userEmail', 'phone')
  1114. NickName = qs[0]['NickName']
  1115. phone = qs[0]['phone']
  1116. username = qs[0]['username']
  1117. qs = CommonService.qs_to_list(qs)
  1118. if NickName == '':
  1119. qs[0]['NickName'] = username
  1120. if phone == '':
  1121. qs[0]['phone'] = NickName
  1122. return response.json(0, qs)
  1123. @staticmethod
  1124. def test_tool_del_device(request_dict, response):
  1125. """
  1126. 测试工具删除设备
  1127. @param request_dict: 请求数据
  1128. @request_dict uid: uid
  1129. @request_dict time_stamp: 时间戳
  1130. @request_dict time_stamp_token: 时间戳token
  1131. @param response: 响应
  1132. @return: response
  1133. """
  1134. uid = request_dict.get('uid')
  1135. time_stamp = request_dict.get('time_stamp', None)
  1136. time_stamp_token = request_dict.get('time_stamp_token', None)
  1137. if not all([uid, time_stamp, time_stamp_token]):
  1138. return response.json(444)
  1139. try:
  1140. # 时间戳token校验
  1141. if not CommonService.check_time_stamp_token(time_stamp_token, time_stamp):
  1142. return response.json(13)
  1143. with transaction.atomic():
  1144. Device_Info.objects.filter(UID=uid).delete()
  1145. UidPushModel.objects.filter(uid_set__uid=uid).delete()
  1146. LOGGER.info(f'PC删除设备&删除APP推送token{uid}成功')
  1147. asy = threading.Thread(target=EquipmentManagerV3.async_del_message, args=(uid,))
  1148. asy.start()
  1149. return response.json(0, {'msg': 'Delete the device and delete the push token successfully'})
  1150. except Exception as e:
  1151. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  1152. def change_device_password(self, request_dict, response):
  1153. """
  1154. 修改设备密码
  1155. @return:
  1156. """
  1157. uid = request_dict.get('uid', None)
  1158. version = request_dict.get('version', None)
  1159. encrypt_pwd = request_dict.get('encrypt_pwd', None)
  1160. if not all([uid, version, encrypt_pwd]):
  1161. return response.json(444)
  1162. try:
  1163. # 异步请求其他服
  1164. if CONFIG_INFO == CONFIG_US:
  1165. change_pwd_thread = threading.Thread(target=self.change_pwd, args=(request_dict.dict(),))
  1166. change_pwd_thread.start()
  1167. view_password = self.decode_pwd(encrypt_pwd)
  1168. Device_Info.objects.filter(UID=uid).update(View_Password=view_password)
  1169. UidSetModel.objects.filter(uid=uid).update(pwd=view_password)
  1170. content = json.loads(json.dumps(request_dict))
  1171. log = {
  1172. 'user_id': 2,
  1173. 'status': 200,
  1174. 'time': int(time.time()),
  1175. 'url': 'v3/equipment/changeDevicePassword',
  1176. 'content': json.dumps(content),
  1177. 'operation': '{}上报设备密码:{}'.format(uid, view_password),
  1178. }
  1179. LogModel.objects.create(**log)
  1180. return response.json(0)
  1181. except Exception as e:
  1182. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  1183. @staticmethod
  1184. def change_pwd(data):
  1185. """
  1186. 请求更新密码线程
  1187. @param data: 请求数据
  1188. """
  1189. orders_domain_name_list = CommonService.get_orders_domain_name_list()
  1190. for domain_name in orders_domain_name_list:
  1191. url = '{}v3/equipment/changeDevicePassword'.format(domain_name)
  1192. requests.post(url=url, data=data, timeout=30)
  1193. def do_get_device_features(self, request_dict, response):
  1194. uid = request_dict.get('uid', None)
  1195. if uid:
  1196. uid = CommonService.decode_data(uid)
  1197. if uid:
  1198. uid_qs = UidSetModel.objects.filter(uid=uid)
  1199. if uid_qs.exists():
  1200. uid_qs = uid_qs.values('is_alexa', 'is_human', 'is_custom_voice', 'double_wifi', 'mobile_4g')
  1201. return response.json(0, uid_qs[0])
  1202. else:
  1203. return response.json(173)
  1204. else:
  1205. return response.json(444)
  1206. else:
  1207. return response.json(444)
  1208. @classmethod
  1209. def async_del_message(cls, uid):
  1210. try:
  1211. # 删除推送消息
  1212. EquipmentInfoService.delete_all_equipment_info(device_uid=uid)
  1213. serial_number = CommonService.get_serial_number_by_uid(uid)
  1214. # 删除iccid用户信息
  1215. iccid_info_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_number)
  1216. if iccid_info_qs:
  1217. iccid_info_qs.update(status=2, updated_time=int(time.time()), user_id='')
  1218. except Exception as e:
  1219. LOGGER.info('EquipmentManagerV3.async_del_message,{},error_line:{}, error_msg:{}'
  1220. .format(uid, e.__traceback__.tb_lineno, repr(e)))
  1221. @staticmethod
  1222. def save_button_user(request_dict, response):
  1223. """
  1224. 设置推送按钮用户
  1225. """
  1226. uid = request_dict.get('uid', None)
  1227. button_user1 = request_dict.get('buttonUser1', None)
  1228. button_user2 = request_dict.get('buttonUser2', None)
  1229. if not uid:
  1230. return response.json(444)
  1231. try:
  1232. now_time = int(time.time())
  1233. if button_user1:
  1234. button_qs = UserAudioVideoPush.objects.filter(uid=uid)
  1235. if button_qs.exists():
  1236. button_qs.update(buttonUser1=button_user1, updated_time=now_time)
  1237. else:
  1238. UserAudioVideoPush.objects.create(uid=uid, buttonUser1=button_user1, created_time=now_time,
  1239. updated_time=now_time)
  1240. if button_user2:
  1241. button_qs = UserAudioVideoPush.objects.filter(uid=uid)
  1242. if button_qs.exists():
  1243. button_qs.update(buttonUser2=button_user2, updated_time=now_time)
  1244. else:
  1245. UserAudioVideoPush.objects.create(uid=uid, buttonUser2=button_user2, created_time=now_time,
  1246. updated_time=now_time)
  1247. return response.json(0)
  1248. except Exception as e:
  1249. return response.json(500, repr(e))
  1250. @staticmethod
  1251. def get_button_user(request_dict, response):
  1252. """
  1253. 获取推送按钮用户
  1254. """
  1255. uid = request_dict.get('uid', None)
  1256. if not uid:
  1257. return response.json(444)
  1258. try:
  1259. device_qs = Device_Info.objects.filter(UID=uid).values('userID', 'userID__NickName', 'noteName')
  1260. button_qs = UserAudioVideoPush.objects.filter(uid=uid).values('buttonUser1', 'buttonUser2')
  1261. res = []
  1262. for item in device_qs:
  1263. noteName = item['noteName'] if item['noteName'] else item['userID__NickName']
  1264. temp_dict = {'userId': item['userID'], 'username': item['userID__NickName'],
  1265. 'noteName': noteName}
  1266. if not button_qs.exists():
  1267. res.append(temp_dict)
  1268. continue
  1269. if item['userID'] == button_qs[0]['buttonUser1']:
  1270. temp_dict['audioVideoButton'] = '1'
  1271. if item['userID'] == button_qs[0]['buttonUser2']:
  1272. temp_dict['audioVideoButton'] = '2'
  1273. if item['userID'] == button_qs[0]['buttonUser1'] and item['userID'] == button_qs[0]['buttonUser2']:
  1274. temp_dict['audioVideoButton'] = '1,2'
  1275. res.append(temp_dict)
  1276. return response.json(0, res)
  1277. except Exception as e:
  1278. return response.json(500, repr(e))
  1279. @staticmethod
  1280. def verify_code(request_dict, response):
  1281. """
  1282. 校验验证码(查看设备密码)
  1283. @param request_dict:
  1284. @param response:
  1285. @return:
  1286. """
  1287. email = request_dict.get('email', None)
  1288. phone = request_dict.get('phone', None)
  1289. uid = request_dict.get('uid', None)
  1290. authcode = request_dict.get('authcode', None)
  1291. if not any([email, phone]):
  1292. return response.json(444)
  1293. if not all([uid, authcode]):
  1294. return response.json(444)
  1295. try:
  1296. authcode = CommonService.decode_data(authcode.strip())
  1297. if authcode is None:
  1298. return response.json(444, 'authcode')
  1299. user_info = email if email is not None else phone
  1300. redis = RedisObject()
  1301. redis_key = '{}_{}_GetDevicePassword'.format(user_info, uid)
  1302. reset_code = redis.get_data(key=redis_key)
  1303. if reset_code is False:
  1304. return response.json(90)
  1305. if authcode != reset_code:
  1306. return response.json(121)
  1307. if not redis.del_data(redis_key):
  1308. return response.json(10, '删除缓存失败')
  1309. return response.json(0)
  1310. except Exception as e:
  1311. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  1312. @staticmethod
  1313. def view_device_password(request_dict, response):
  1314. """
  1315. 查看设备密码
  1316. @param request_dict:
  1317. @param response:
  1318. @return:
  1319. """
  1320. uid = request_dict.get('uid', None)
  1321. if not all([uid]):
  1322. return response.json(444)
  1323. try:
  1324. uid_set_qs = UidSetModel.objects.filter(uid=uid).values('pwd')
  1325. if uid_set_qs.exists():
  1326. device_password = uid_set_qs[0]['pwd']
  1327. else:
  1328. device_info_qs = Device_Info.objects.filter(UID=uid).values('View_Password')
  1329. if not device_info_qs.exists():
  1330. return response.json(173)
  1331. device_password = device_info_qs[0]['View_Password']
  1332. device_password = CommonService.encode_data(device_password)
  1333. res = {
  1334. 'device_password': device_password
  1335. }
  1336. return response.json(0, res)
  1337. except Exception as e:
  1338. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  1339. @staticmethod
  1340. def edit_sort_order(user_id, request_dict, response):
  1341. """
  1342. 修改设备排序
  1343. ids: 选中的设备id列表(单选或多选)
  1344. action: 操作类型(move/top/bottom)
  1345. target_id: 拖动目标id(仅单选拖动时用)
  1346. """
  1347. ids = request_dict.get('ids', None)
  1348. action = request_dict.get('action', None)
  1349. target_id = request_dict.get('target_id', None)
  1350. if not ids or not action:
  1351. return response.json(444, 'ids or action missing')
  1352. try:
  1353. ids = ids.split(',')
  1354. # 查询所有设备,按sort_order排序
  1355. all_devices = list(Device_Info.objects.filter(userID_id=user_id).exclude(Type__in=[200, 201]).
  1356. order_by('-sort_order', '-data_joined'))
  1357. id_to_device = {str(d.id): d for d in all_devices}
  1358. # 单选拖动排序
  1359. if action == 'move' and len(ids) == 1 and target_id:
  1360. moving_id = ids[0]
  1361. moving_device = id_to_device.get(str(moving_id))
  1362. # 如果要移动到最前面,设置target_index为0
  1363. if target_id == 'front':
  1364. target_index = 0
  1365. else:
  1366. target_device = id_to_device.get(str(target_id))
  1367. target_index = all_devices.index(target_device)
  1368. all_devices.remove(moving_device)
  1369. all_devices.insert(target_index, moving_device)
  1370. # 勾选框批量置顶/置底
  1371. elif action in ('top', 'bottom'):
  1372. selected_devices = [id_to_device[i] for i in ids if i in id_to_device]
  1373. other_devices = [d for d in all_devices if str(d.id) not in ids]
  1374. if action == 'top':
  1375. all_devices = selected_devices + other_devices
  1376. else:
  1377. all_devices = other_devices + list(reversed(selected_devices))
  1378. # 重新赋值sort_order
  1379. for idx, device in enumerate(all_devices):
  1380. device.sort_order = len(all_devices) - idx
  1381. device.save(update_fields=['sort_order'])
  1382. return response.json(0)
  1383. except Exception as e:
  1384. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  1385. @classmethod
  1386. def get_device_list_by_user_id(cls, user_id, response):
  1387. """
  1388. 根据用户ID获取设备列表(设备名称、UID、序列号、类型)
  1389. Args:
  1390. user_id: 用户ID
  1391. response: 响应对象
  1392. Returns:
  1393. Response: 包含设备列表的响应对象
  1394. """
  1395. # 输入参数验证
  1396. if not user_id:
  1397. LOGGER.warning("获取设备列表失败: 用户ID为空")
  1398. return response.json(400, "用户ID不能为空")
  1399. try:
  1400. # 使用链式查询优化,减少数据库查询次数
  1401. device_queryset = (
  1402. Device_Info.objects
  1403. .filter(
  1404. userID=user_id,
  1405. )
  1406. .exclude(Type__in=[200, 201]) # 排除网关和插座类型
  1407. .only('NickName', 'UID', 'serial_number', 'Type') # 仅查询需要的字段
  1408. .order_by('-sort_order') # 添加排序,提高用户体验
  1409. )
  1410. # 直接使用values()返回字典列表,避免创建模型实例
  1411. device_data = list(
  1412. device_queryset.values(
  1413. 'NickName',
  1414. 'UID',
  1415. 'serial_number',
  1416. 'Type'
  1417. )
  1418. )
  1419. # 添加空数据检查
  1420. if not device_data:
  1421. return response.json(0, [])
  1422. return response.json(0, device_data)
  1423. except Exception as e:
  1424. # 其他异常
  1425. LOGGER.error(
  1426. f"用户 {user_id} 获取设备列表时发生未知异常: {repr(e)}",
  1427. exc_info=True # 记录完整的堆栈信息
  1428. )
  1429. return response.json(500, "系统内部错误")
  1430. def get_device_detail_by_uid(self, user_id, request_dict, response):
  1431. """
  1432. 根据USER_ID、UID查询设备详情
  1433. @param userID: 用户id
  1434. @param request_dict: 请求参数
  1435. @param response: 响应结果
  1436. """
  1437. try:
  1438. uid = request_dict.get('uid', None)
  1439. if not uid:
  1440. return response.json(444)
  1441. all_dv_list, _ = UserDeviceService.query_device_list(
  1442. user_id,
  1443. uid=uid,
  1444. nickname=None,
  1445. page=1,
  1446. line=500,
  1447. group_id=0
  1448. )
  1449. matched_dv = all_dv_list
  1450. search_uids = [dev['UID'] for dev in matched_dv]
  1451. ub_qs = UserDeviceService.query_device_uid_bucket(search_uids) # 根据uid集合查询云存套餐
  1452. up_qs = UserDeviceService.query_device_preview(search_uids) # 根据uid集合查询设备预览图
  1453. uv_dict = UserDeviceService.query_device_channel(search_uids) # 查询设备uid通道配置属性
  1454. auth = oss2.Auth(ALICLOUD_AK, ALICLOUD_SK)
  1455. bucket = oss2.Bucket(auth, 'oss-cn-hongkong.aliyuncs.com', 'statres')
  1456. nowTime = int(time.time())
  1457. data = []
  1458. # 遍历所有匹配的设备,查询设备关联数据详情
  1459. for p in matched_dv:
  1460. p['UID'] = p['UID'].replace('\n', '').replace('\r', '')
  1461. p_uid = p['UID'].upper()
  1462. UserDeviceService.get_sim_by_serial_number(p) # 获取SIM卡属性
  1463. p['cloudPhoto'] = self.get_cloud_photo_status(p['UID'])
  1464. # 获取云存使用状态
  1465. p['vod_use_status'] = self.get_vod_use_status(p_uid, nowTime)
  1466. # 获取iot_deviceInfo表的endpoint和token_iot_number
  1467. p['iot'] = []
  1468. if p['serial_number']: # 存在序列号根据序列号查询
  1469. iotdeviceInfo_qs = iotdeviceInfoModel.objects.filter(serial_number=p['serial_number'][0:6])
  1470. else: # 根据uid查询
  1471. iotdeviceInfo_qs = iotdeviceInfoModel.objects.filter(uid=p_uid)
  1472. if iotdeviceInfo_qs.exists():
  1473. iotdeviceInfo = iotdeviceInfo_qs.values('endpoint', 'token_iot_number')
  1474. p['iot'].append({
  1475. 'endpoint': iotdeviceInfo[0]['endpoint'],
  1476. 'token_iot_number': iotdeviceInfo[0]['token_iot_number']
  1477. })
  1478. p['vod'] = []
  1479. for dm in ub_qs:
  1480. if p_uid == dm['uid']:
  1481. if dm['endTime'] > nowTime:
  1482. p['vod'].append(dm)
  1483. p['preview'] = []
  1484. for up in up_qs:
  1485. if p_uid == up['uid']:
  1486. obj = 'uid_preview/{uid}/channel_{channel}.png'.format(uid=up['uid'], channel=up['channel'])
  1487. img_sign = bucket.sign_url('GET', obj, 300)
  1488. p['preview'].append(img_sign)
  1489. UserDeviceService.get_uid_info(p, p_uid) # 获取uid初始化信息
  1490. if p_uid in uv_dict:
  1491. # 获取设备信息DTO
  1492. UserDeviceService.get_device_info_dto(p, p_uid, uv_dict, user_id)
  1493. else:
  1494. # 设备版本号
  1495. p['uid_version'] = ''
  1496. p['ucode'] = ''
  1497. p['View_Password'] = self.encrypt_pwd(p['View_Password'])
  1498. # 判断设备是否支持4G和查询移动侦测状态
  1499. uid_set_qs = UidSetModel.objects.filter(uid=p['UID']).values('detect_status', 'ucode', 'version')
  1500. if uid_set_qs.exists():
  1501. uid_set_qs = uid_set_qs.first()
  1502. p['has_4g_cloud'] = self.get_device_is_4G(uid_set_qs['ucode'], uid_set_qs['version'])
  1503. if p['has_4g_cloud'] == 1:
  1504. p['isCameraOpenCloud'] = 1
  1505. p['NotificationMode'] = uid_set_qs['detect_status']
  1506. data.append(p)
  1507. return response.json(0, data)
  1508. except Exception as e:
  1509. LOGGER.error(f"{user_id}查询设备详情时发生错误: {str(e)}")
  1510. return response.json(500)