index.py 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. @Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
  5. @AUTHOR: ASJRD018
  6. @NAME: azoauth
  7. @software: PyCharm
  8. @DATE: 2020/1/13 17:01
  9. @Version: python3.6
  10. @MODIFY DECORD:ansjer dev
  11. @file: index.py
  12. @Contact: chanjunkai@163.com
  13. """
  14. import json
  15. import threading
  16. import time
  17. import requests
  18. import logging
  19. from django.views.generic import TemplateView
  20. from django.shortcuts import render_to_response
  21. from django.http import JsonResponse
  22. from object.ResObject import ResObject
  23. from urllib.parse import urlencode
  24. import subprocess
  25. import uuid
  26. # from gevent.pool import Pool
  27. from model.models import UserModel, UidRtspModel, AlexaAuthModel, UserCountModel, SwitchModel
  28. from object.ResponseObject import ResponseObject
  29. from object.tkObject import tkObject
  30. from service.CommonService import CommonService
  31. from object.RedisObject import RedisObject
  32. from azoauth.config import *
  33. from datetime import datetime
  34. class authView(TemplateView):
  35. def post(self, request, *args, **kwargs):
  36. request.encoding = 'utf-8'
  37. request_dict = json.loads(request.body.decode('utf-8'))
  38. return self.validate(request_dict)
  39. def get(self, request, *args, **kwargs):
  40. request.encoding = 'utf-8'
  41. request_dict = request.GET
  42. return self.validate(request_dict)
  43. def validate(self, request_dict):
  44. logger = logging.getLogger('django')
  45. logger.info('------oa2/auth请求参数: {}------'.format(request_dict))
  46. state = request_dict.get("state", '')
  47. client_id = request_dict.get("client_id", '')
  48. response_type = request_dict.get("response_type", '')
  49. scope = request_dict.get("scope", '')
  50. redirect_uri = request_dict.get("redirect_uri", '')
  51. context = {
  52. 'state': state,
  53. 'client_id': client_id,
  54. 'response_type': response_type,
  55. 'scope': scope,
  56. 'redirect_uri': redirect_uri,
  57. 'skill_name': 'zosi smart'
  58. }
  59. return render_to_response("login.html", context)
  60. # Anlapus登录
  61. class authAnlapusView(TemplateView):
  62. def post(self, request, *args, **kwargs):
  63. request.encoding = 'utf-8'
  64. request_dict = json.loads(request.body.decode('utf-8'))
  65. return self.validate(request_dict)
  66. def get(self, request, *args, **kwargs):
  67. request.encoding = 'utf-8'
  68. request_dict = request.GET
  69. return self.validate(request_dict)
  70. def validate(self, request_dict):
  71. state = request_dict.get("state", '')
  72. client_id = request_dict.get("client_id", '')
  73. response_type = request_dict.get("response_type", '')
  74. scope = request_dict.get("scope", '')
  75. redirect_uri = request_dict.get("redirect_uri", '')
  76. context = {
  77. 'state': state,
  78. 'client_id': client_id,
  79. 'response_type': response_type,
  80. 'scope': scope,
  81. 'redirect_uri': redirect_uri,
  82. 'skill_name': 'Anlapus'
  83. }
  84. return render_to_response("login_anlapus.html", context)
  85. # loocam登录
  86. class authLoocamView(TemplateView):
  87. def post(self, request, *args, **kwargs):
  88. request.encoding = 'utf-8'
  89. request_dict = json.loads(request.body.decode('utf-8'))
  90. return self.validate(request_dict)
  91. def get(self, request, *args, **kwargs):
  92. request.encoding = 'utf-8'
  93. request_dict = request.GET
  94. return self.validate(request_dict)
  95. def validate(self, request_dict):
  96. state = request_dict.get("state", '')
  97. client_id = request_dict.get("client_id", '')
  98. response_type = request_dict.get("response_type", '')
  99. scope = request_dict.get("scope", '')
  100. redirect_uri = request_dict.get("redirect_uri", '')
  101. context = {
  102. 'state': state,
  103. 'client_id': client_id,
  104. 'response_type': response_type,
  105. 'scope': scope,
  106. 'redirect_uri': redirect_uri,
  107. 'skill_name': 'loocam'
  108. }
  109. logger = logging.getLogger('django')
  110. logger.info('loocam请求登录网页,参数为{}'.format(context))
  111. return render_to_response("login_loocam.html", context)
  112. class loginHandleView(TemplateView):
  113. def post(self, request, *args, **kwargs):
  114. request.encoding = 'utf-8'
  115. request_dict = json.loads(request.body.decode('utf-8'))
  116. return self.validate(request_dict)
  117. def get(self, request, *args, **kwargs):
  118. request.encoding = 'utf-8'
  119. request_dict = request.GET
  120. return self.validate(request_dict)
  121. def validate(self, request_dict):
  122. response = ResObject()
  123. user = request_dict.get("user", '')
  124. pwd = request_dict.get("pwd", '')
  125. state = request_dict.get("state", '')
  126. client_id = request_dict.get("client_id", '')
  127. response_type = request_dict.get("response_type", '')
  128. scope = request_dict.get("scope", '')
  129. redirect_uri = request_dict.get("redirect_uri", '')
  130. skill_name = request_dict.get("skill_name", '')
  131. # 返回code
  132. logger = logging.getLogger('django')
  133. logger.info('------开始认证登录------')
  134. logger.info('userName: {}, userPwd: {}, redirect_uri: {}'.format(user, pwd, redirect_uri))
  135. if client_id != 'azalexaclient' or response_type != 'code' or scope != 'profile':
  136. return response.json(10, res={'msg': 'error'}, extra={'msg': 'message wrong'})
  137. auth_request_url = '{SERVER_PREFIX}/oalexa/auth'.format(SERVER_PREFIX=SERVER_PREFIX)
  138. requests_data = {'userName': user, 'userPwd': pwd}
  139. res = requests.post(url=auth_request_url, data=requests_data)
  140. if res.status_code != 200:
  141. return response.json(10, res={'错误': '请求响应异常'})
  142. res_json = res.json()
  143. logger.info('国外服务器响应: {}'.format(res_json))
  144. # 添加测试服务器测试
  145. if res_json['result_code'] != 0:
  146. auth_request_url = '{SERVER_PREFIX}/oalexa/auth'.format(SERVER_PREFIX=SERVER_PREFIX_TEST)
  147. res = requests.post(url=auth_request_url, data=requests_data)
  148. if res.status_code != 200:
  149. return response.json(10, res={'错误': '请求响应异常'})
  150. res_json = res.json()
  151. logger.info('请求服务器url: {}'.format(auth_request_url))
  152. logger.info('服务器响应: {}'.format(res_json))
  153. if res_json['result_code'] != 0:
  154. return response.json(10, res={'msg': 'error'}, extra={'msg': res_json['reason']})
  155. nowTime = int(time.time())
  156. code = CommonService.encrypt_data(32)
  157. userID = res_json['result']['userID']
  158. user_qs = UserModel.objects.filter(userID=userID)
  159. if user_qs.exists():
  160. user_qs.update(code=code, updTime=nowTime)
  161. else:
  162. UserModel.objects.create(userID=userID, code=code, addTime=nowTime, updTime=nowTime)
  163. year_month = str(time.strftime('%Y%m', time.localtime(nowTime))) # 获取当前年月
  164. user_count_qs = UserCountModel.objects.filter(skill_name=skill_name, year_month=year_month).values('amount')
  165. if not user_count_qs.exists():
  166. UserCountModel.objects.create(skill_name=skill_name, year_month=year_month, amount=1)
  167. else:
  168. # 用户数量+1
  169. amount = user_count_qs[0]['amount'] + 1
  170. user_count_qs.update(amount=amount)
  171. redirect_uri += '?code=' + code + '&state=' + state
  172. return response.json(0, res=redirect_uri)
  173. class oa2TokenView(TemplateView):
  174. def post(self, request, *args, **kwargs):
  175. request.encoding = 'utf-8'
  176. # request_dict = json.loads(request.body.decode('utf-8'))
  177. request_dict = request.POST
  178. return self.validate(request_dict)
  179. def get(self, request, *args, **kwargs):
  180. request.encoding = 'utf-8'
  181. request_dict = request.GET
  182. return self.validate(request_dict)
  183. def validate(self, request_dict):
  184. # 增加对code和client_id的校验代码,返回access_token和refresh_token
  185. code = request_dict.get("code", None)
  186. client_id = request_dict.get("client_id", None)
  187. refresh_token = request_dict.get("refresh_token", None)
  188. logger = logging.getLogger('django')
  189. logger.info('token-------------begin--------')
  190. logger.info(code)
  191. logger.info(client_id)
  192. logger.info(refresh_token)
  193. logger.info(request_dict)
  194. print('client_id:')
  195. print(client_id)
  196. user_qs = UserModel.objects.filter(code=code)
  197. if not user_qs.exists():
  198. user_qs = UserModel.objects.filter(refresh_token=refresh_token)
  199. if user_qs.exists():
  200. access_token = CommonService.encrypt_data(randomlength=32)
  201. refresh_token = CommonService.encrypt_data(randomlength=32)
  202. is_update = user_qs.update(access_token=access_token, refresh_token=refresh_token)
  203. print(is_update)
  204. if is_update:
  205. res_json = {
  206. "access_token": access_token,
  207. "token_type": "bearer",
  208. "expires_in": 3600,
  209. "refresh_token": refresh_token,
  210. # 'test': 'joker'
  211. }
  212. logger.info(res_json)
  213. return JsonResponse(res_json)
  214. else:
  215. logger.info({'msg': 'error'})
  216. return JsonResponse({'msg': 'error'})
  217. else:
  218. res_json = {'msg': 'code not exists'}
  219. return JsonResponse(res_json)
  220. def runSendRtspMsg_thread(UID, PWD, MSG):
  221. command = "./pushtool {UID} {PWD} {MSG} 1".format(UID=UID, PWD=PWD, MSG=MSG)
  222. print('command=>{command}'.format(command=command))
  223. try:
  224. back = subprocess. \
  225. Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE). \
  226. communicate(timeout=10)
  227. except Exception as e:
  228. return False
  229. else:
  230. print("back0----", back[0].decode()) # 注意需要进行解码操作,默认输出的是字节
  231. print("back1----", back[1].decode()) # back是一个元祖,可以通过元祖取值的方式获取结果
  232. return True
  233. class oa2RtspStartView(TemplateView):
  234. def post(self, request, *args, **kwargs):
  235. request.encoding = 'utf-8'
  236. request_dict = request.POST
  237. return self.validate(request_dict)
  238. def get(self, request, *args, **kwargs):
  239. request.encoding = 'utf-8'
  240. request_dict = request.GET
  241. return self.validate(request_dict)
  242. def validate(self, request_dict):
  243. st = request_dict.get("st", 0)
  244. uid = request_dict.get("id", '')
  245. access_token = request_dict.get("access_token", '')
  246. skill_name = request_dict.get("skill_name", 'zosi smart')
  247. user_qs = UserModel.objects.filter(access_token=access_token)
  248. if not user_qs.exists():
  249. return JsonResponse({'错误': '用户数据不存在'})
  250. ur_qs = UidRtspModel.objects.filter(uid=uid).values('uid', 'nick', 'rtsp_url', 'password', 'region')
  251. if not ur_qs.exists():
  252. return JsonResponse({'错误': 'uid数据不存在'})
  253. UID = ur_qs[0]['uid']
  254. nick = ur_qs[0]['nick']
  255. PWD = ur_qs[0]['password']
  256. region = ur_qs[0]['region']
  257. stream_name = ur_qs[0]['rtsp_url']
  258. channel = '0'
  259. if '_' in UID:
  260. # 多通道设备
  261. channel = UID[-1:]
  262. UID = UID[:-2]
  263. RESP_SERVER_DOMAIN = RESP_SERVER_DOMAIN_DATA[region]
  264. MSG = '{}://{}:8554/{}'.format(RTSP_PREFIX, RESP_SERVER_DOMAIN, stream_name)
  265. logger = logging.getLogger('django')
  266. logger.info('------{} 开始向设备下发推流指令------'.format(skill_name))
  267. # 此处后续应该用异步去发送指令
  268. if int(st) == 1:
  269. send_flag = self.runSendStop(UID, PWD, MSG)
  270. logger.info('----------send_flag---st=1-----------------')
  271. if send_flag:
  272. return JsonResponse({'msg': 'stop yes', 'code': 0})
  273. else:
  274. return JsonResponse({'msg': 'stop no', 'code': 0})
  275. # pushtool指令
  276. command = "./pushtool {UID} {PWD} {MSG} 1 {channel}".format(UID=UID, PWD=PWD, MSG=MSG, channel=channel)
  277. # 请求MQTT发布消息
  278. url = '{}/iot/requestPublishMessage'.format(SERVER_PREFIX)
  279. requests_data = {'UID': UID, 'rtsp': MSG, 'enable': '1'} # 1: 开始推流,0: 停止推流; channel: 推流通道
  280. r = requests.post(url, requests_data)
  281. if r.status_code == 200:
  282. res = r.json()
  283. logger.info('请求MQTT发布消息参数:{},result_code: {}'.format(requests_data, res['result_code']))
  284. if res['result_code'] == 0:
  285. logger.info('请求MQTT下发指令成功---正式服')
  286. elif res['result_code'] == 10044:
  287. url = '{}/iot/requestPublishMessage'.format(SERVER_PREFIX_TEST) # 测试服务器
  288. r = requests.post(url, requests_data)
  289. if r.status_code == 200:
  290. res = r.json()
  291. if res['result_code'] == 0:
  292. logger.info('请求MQTT下发指令成功---测试服')
  293. else:
  294. self.runSendRtspMsg(logger, region, command)
  295. else:
  296. self.runSendRtspMsg(logger, region, command)
  297. else:
  298. self.runSendRtspMsg(logger, region, command)
  299. else: # 使用pushtool通知设备推流
  300. self.runSendRtspMsg(logger, region, command)
  301. # 拉流地址
  302. rtsp_uri = '{}://{}:443/{}'.format(RTSP_PREFIX, RESP_SERVER_DOMAIN, stream_name)
  303. stop_time = int(time.time()) + 2 * 60
  304. expirationTime = time.strftime('%Y-%m-%dT%H:%MZ', time.localtime(stop_time))
  305. res_json = {
  306. 'uid': UID,
  307. 'pwd': PWD,
  308. 'msg': MSG,
  309. 'uri': rtsp_uri,
  310. 'endpointId': uid,
  311. 'friendlyName': nick,
  312. 'manufacturerName': skill_name,
  313. 'expirationTime': expirationTime,
  314. 'description': 'Camera connected via {}'.format(skill_name),
  315. 'audioCodecs': 'ACC',
  316. 'videoCodecs': 'H264',
  317. 'protocols': ['RTSP'],
  318. 'idleTimeoutSeconds': 5,
  319. 'modelName': 'P1425-LE',
  320. 'authorizationTypes': ['NONE'],
  321. 'manufacturerId': 'zosi-ACCC8E5E7513',
  322. 'resolutions': {'width': 640, 'height': 360},
  323. }
  324. logger.info('------------返回控制摄像头的信息---------------: {}'.format(res_json))
  325. return JsonResponse(res_json, safe=False)
  326. def runReqRtspMsg(self, UID, PWD, MSG):
  327. request_url = 'http://localhost:5000/?UID={UID}&MSG={MSG}&CMD=1&PWD={PWD}'. \
  328. format(UID=UID, PWD=PWD, MSG=MSG)
  329. res = requests.get(url=request_url)
  330. print(res)
  331. return True
  332. # 触发此方法,让摄像头推流到MSG流地址
  333. def runSendRtspMsg(self, logger, region, command):
  334. logger.info('------------推流指令: {}---------------'.format(command))
  335. if region == 'CN':
  336. logger.info('------------国内发送推流指令---------------')
  337. url = "http://52.83.252.41:7880/alexa/command?command={command}".format(command=command)
  338. # 请求国内服务器调用pushtool
  339. try:
  340. requests.get(url=url, timeout=10)
  341. except Exception as e:
  342. logger.info('请求国内服务器调用pushtool异常: {}'.format(repr(e)))
  343. else:
  344. logger.info('------------国外发送推流指令---------------')
  345. try:
  346. back = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE). \
  347. communicate(timeout=10)
  348. logger.info('back: {}'.format(str(back[0].decode()) + str(back[1].decode())))
  349. except Exception as e:
  350. self.runSendRtspMsg(logger, 'CN', command) # 调用失败时尝试用国内的发送
  351. logger.info('调用pushtool异常: {}'.format(repr(e)))
  352. def runSendStop(self, UID, PWD, MSG):
  353. command = "./pushtool {UID} {PWD} {MSG} 0".format(UID=UID, PWD=PWD, MSG=MSG)
  354. print('command=>{command}'.format(command=command))
  355. try:
  356. back = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE). \
  357. communicate(timeout=10)
  358. except Exception as e:
  359. return False
  360. else:
  361. print("back0----", back[0].decode()) # 注意需要进行解码操作,默认输出的是字节
  362. print("back1----", back[1].decode()) # back是一个元祖,可以通过元祖取值的方式获取结果
  363. return True
  364. class oa2DiscoveryDevice(TemplateView):
  365. def post(self, request, *args, **kwargs):
  366. request.encoding = 'utf-8'
  367. request_dict = request.POST
  368. return self.validate(request_dict)
  369. def get(self, request, *args, **kwargs):
  370. request.encoding = 'utf-8'
  371. request_dict = request.GET
  372. return self.validate(request_dict)
  373. def validate(self, request_dict):
  374. # 增加对code和client_id的校验代码,返回access_token和refresh_token
  375. skill_name = request_dict.get("skill_name", 'zosi smart')
  376. access_token = request_dict.get("access_token", None)
  377. logger = logging.getLogger('django')
  378. logger.info('--------{} 开始搜索设备--------'.format(skill_name))
  379. response = ResObject()
  380. user_qs = UserModel.objects.filter(access_token=access_token)
  381. if not user_qs.exists():
  382. return response.json(500, res={'msg': '用户数据不存在'})
  383. user = user_qs[0]
  384. userID = user.userID
  385. logger.info('userID: {}'.format(userID))
  386. # 更新事件网关接口
  387. alexAuth = AlexaAuthModel.objects.filter(token=access_token, skill_name=skill_name).order_by('-addTime')
  388. if alexAuth.exists():
  389. auth_res = alexAuth.values()
  390. event_access_token = auth_res[0]['access_token']
  391. event_refresh_token = auth_res[0]['refresh_token']
  392. event_token = auth_res[0]['token']
  393. event_expiresTime = auth_res[0]['expiresTime']
  394. event_addTime = auth_res[0]['addTime']
  395. event_updTime = auth_res[0]['updTime']
  396. event_alexa_region = auth_res[0]['alexa_region']
  397. AlexaAuthModel.objects.filter(userID=userID).delete()
  398. alexAuth.delete()
  399. logger.info('update_event_access_token')
  400. logger.info(event_token)
  401. AlexaAuthModel.objects.create(
  402. userID=userID,
  403. access_token=event_access_token,
  404. refresh_token=event_refresh_token,
  405. token=event_token,
  406. expiresTime=event_expiresTime,
  407. addTime=event_addTime,
  408. updTime=event_updTime,
  409. alexa_region=event_alexa_region,
  410. skill_name=skill_name,
  411. )
  412. auth_request_url = '{}/oalexa/discoveryuid'.format(SERVER_PREFIX)
  413. requests_data = {'sid': 'admin', 'sst': 'admin', 'alexa_user_id': userID}
  414. res = requests.post(url=auth_request_url, data=requests_data)
  415. res_json = res.json()
  416. logger.info('正式服务器响应: {}'.format(res_json))
  417. test_flag = False # 用来区分测试服务器,后面删掉
  418. # 添加测试服务器测试
  419. if res_json['result_code'] != 0:
  420. auth_request_url = '{}/oalexa/discoveryuid'.format(SERVER_PREFIX_TEST)
  421. res = requests.post(url=auth_request_url, data=requests_data)
  422. res_json = res.json()
  423. test_flag = True
  424. logger.info('请求服务器url: {}'.format(auth_request_url))
  425. logger.info('服务器响应: {}'.format(res_json))
  426. if res_json['result_code'] != 0:
  427. return response.json(500, res={'msg': '请求业务服务器接口result_code不为0'})
  428. uid_arr = res_json['result']['uid_arr']
  429. rtko = tkObject(rank=1)
  430. now_time = int(time.time())
  431. user.uid_rtsp.clear()
  432. res_json = []
  433. uid_rtsp_id_list = []
  434. for uid_a in uid_arr:
  435. uid = uid_a['uid']
  436. nick = uid_a['nick']
  437. rtsp_url = rtko.encrypt(data=uid)
  438. region = 'EU' if uid_a['region'] == 'EU' else 'EN'
  439. if test_flag:
  440. multi_channel = uid_a['multi_channel']
  441. if multi_channel:
  442. # 多通道设备: uid_通道号
  443. uid += '_' + str(uid_a['channel'])
  444. try:
  445. uid_rtsp_qs = UidRtspModel.objects.get(uid=uid)
  446. except UidRtspModel.DoesNotExist:
  447. uid_rtsp_qs = UidRtspModel.objects.create(uid=uid, nick=nick, region=region, password=uid_a['password'],
  448. rtsp_url=rtsp_url, addTime=now_time, updTime=now_time)
  449. else:
  450. uid_rtsp_qs.nick = nick
  451. uid_rtsp_qs.region = region
  452. uid_rtsp_qs.password = uid_a['password']
  453. uid_rtsp_qs.save()
  454. uid_rtsp_id_list.append(uid_rtsp_qs.id)
  455. RESP_SERVER_DOMAIN = RESP_SERVER_DOMAIN_DATA[region]
  456. rtsp_uri = '{}://{}:443/{}'.format(RTSP_PREFIX, RESP_SERVER_DOMAIN, rtsp_url)
  457. ur_data = {
  458. 'uri': rtsp_uri,
  459. 'endpointId': uid,
  460. 'friendlyName': nick,
  461. 'manufacturerName': skill_name,
  462. 'description': 'Camera connected via {}'.format(skill_name),
  463. 'protocols': ['RTSP'],
  464. 'audioCodecs': ['ACC'],
  465. 'videoCodecs': ['H264'],
  466. 'modelName': 'P1425-LE',
  467. 'authorizationTypes': ['NONE'],
  468. 'manufacturerId': 'zosi-ACCC8E5E7513',
  469. 'resolutions': [{'width': 640, 'height': 360}],
  470. }
  471. res_json.append(ur_data)
  472. user.uid_rtsp.add(*uid_rtsp_id_list)
  473. logger.info('搜索设备返回值: {}'.format(res_json))
  474. return JsonResponse(res_json, safe=False)
  475. class oa2DiscoverySwitch(TemplateView):
  476. def post(self, request, *args, **kwargs):
  477. request.encoding = 'utf-8'
  478. request_dict = request.POST
  479. return self.validate(request_dict)
  480. def get(self, request, *args, **kwargs):
  481. request.encoding = 'utf-8'
  482. request_dict = request.GET
  483. return self.validate(request_dict)
  484. def validate(self, request_dict):
  485. # 增加对code和client_id的校验代码,返回access_token和refresh_token
  486. skill_name = request_dict.get("skill_name", 'loocam')
  487. access_token = request_dict.get("access_token", None)
  488. logger = logging.getLogger('django')
  489. logger.info('--------{} 开始搜索设备--------'.format(skill_name))
  490. user_qs = UserModel.objects.filter(access_token=access_token)
  491. if not user_qs.exists():
  492. return JsonResponse({'错误': '用户数据不存在'})
  493. response = ResObject()
  494. user = user_qs.first()
  495. userID = user.userID
  496. logger.info('userID: {}'.format(userID))
  497. # 更新事件网关接口
  498. alexAuth = AlexaAuthModel.objects.filter(token=access_token, skill_name=skill_name).order_by('-addTime')
  499. if alexAuth.exists():
  500. auth_res = alexAuth.values()
  501. event_access_token = auth_res[0]['access_token']
  502. event_refresh_token = auth_res[0]['refresh_token']
  503. event_token = auth_res[0]['token']
  504. event_expiresTime = auth_res[0]['expiresTime']
  505. event_addTime = auth_res[0]['addTime']
  506. event_updTime = auth_res[0]['updTime']
  507. event_alexa_region = auth_res[0]['alexa_region']
  508. AlexaAuthModel.objects.filter(userID=userID).delete()
  509. alexAuth.delete()
  510. logger.info('update_event_access_token')
  511. logger.info(event_token)
  512. AlexaAuthModel.objects.create(
  513. userID=userID,
  514. access_token=event_access_token,
  515. refresh_token=event_refresh_token,
  516. token=event_token,
  517. expiresTime=event_expiresTime,
  518. addTime=event_addTime,
  519. updTime=event_updTime,
  520. alexa_region=event_alexa_region,
  521. skill_name=skill_name,
  522. )
  523. auth_request_url = '{}/oalexa/discoveryswitch'.format(SERVER_PREFIX)
  524. requests_data = {'sid': 'admin', 'sst': 'admin', 'alexa_user_id': userID}
  525. res = requests.post(url=auth_request_url, data=requests_data)
  526. res_json = res.json()
  527. logger.info('正式服务器响应: {}'.format(res_json))
  528. # 添加测试服务器测试
  529. if res_json['result_code'] != 0:
  530. auth_request_url = '{}/oalexa/discoveryswitch'.format(SERVER_PREFIX_TEST)
  531. res = requests.post(url=auth_request_url, data=requests_data)
  532. res_json = res.json()
  533. logger.info('请求服务器url: {}'.format(auth_request_url))
  534. logger.info('服务器响应: {}'.format(res_json))
  535. if res_json['result_code'] != 0:
  536. return response.json(0, res={'msg': 'error'})
  537. switch_list = res_json['result']['switch_list']
  538. now_time = int(time.time())
  539. res_json = []
  540. for switch in switch_list:
  541. serial_number = switch['uid']
  542. nick = switch['nick']
  543. region = 'EU' if switch['region'] == 'EU' else 'EN'
  544. switch_info_qs = SwitchModel.objects.filter(serial_number=serial_number, userID=userID)
  545. if switch_info_qs.exists():
  546. switch_info_qs.update(nick=nick, region=region, updTime=now_time)
  547. else:
  548. SwitchModel.objects.create(serial_number=serial_number, nick=nick, region=region, addTime=now_time,
  549. updTime=now_time, userID=userID)
  550. ur_data = {
  551. 'endpointId': serial_number,
  552. 'friendlyName': nick,
  553. 'manufacturerName': skill_name,
  554. 'description': 'Plug connected via {}'.format(skill_name),
  555. 'modelName': 'P1425-LE',
  556. 'manufacturerId': 'zosi-ACCC8E5E7513',
  557. }
  558. res_json.append(ur_data)
  559. logger.info('搜索设备返回值: {}'.format(res_json))
  560. return JsonResponse(res_json, safe=False)
  561. # 新增
  562. def testRunSendStop(request):
  563. request.encoding = 'utf-8'
  564. if request.method == 'GET':
  565. request_dict = request.GET
  566. UID = request_dict.get('UID', None)
  567. PWD = request_dict.get('PWD', None)
  568. MSG = request_dict.get('MSG', None)
  569. command = "./pushtool {UID} {PWD} {MSG} 0".format(UID=UID, PWD=PWD, MSG=MSG)
  570. print('command=>{command}'.format(command=command))
  571. try:
  572. back = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE). \
  573. communicate(timeout=10)
  574. except Exception as e:
  575. return False
  576. else:
  577. print("back0----", back[0].decode()) # 注意需要进行解码操作,默认输出的是字节
  578. print("back1----", back[1].decode()) # back是一个元祖,可以通过元祖取值的方式获取结果
  579. return JsonResponse({'msg': 'stop Stream', 'code': 0})
  580. def testRunStream(request):
  581. request.encoding = 'utf-8'
  582. if request.method == 'GET':
  583. request_dict = request.GET
  584. UID = request_dict.get('UID', None)
  585. PWD = request_dict.get('PWD', None)
  586. MSG = request_dict.get('MSG', None)
  587. time1 = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
  588. command = "./pushtool {UID} {PWD} {MSG} 1".format(UID=UID, PWD=PWD, MSG=MSG)
  589. print('command=>{command}'.format(command=command))
  590. try:
  591. back = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE). \
  592. communicate(timeout=10)
  593. time2 = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
  594. # print("时间:%s"%datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
  595. except Exception as e:
  596. return repr(e)
  597. else:
  598. print("back0----", back[0].decode()) # 注意需要进行解码操作,默认输出的是字节
  599. print("back1----", back[1].decode()) # back是一个元祖,可以通过元祖取值的方式获取结果
  600. # return str(back[0].decode()) + str(back[1].decode())
  601. return JsonResponse({'msg': "star is %s" % time1 + ",end is %s" % time2, 'code': 0})
  602. # return JsonResponse({'msg': "run stream", 'code': 0})
  603. # 测试是否正常接口
  604. def test(request):
  605. return JsonResponse({'msg': 'Server running normal', 'code': 0})
  606. # test接口
  607. def loadBalancingServer(request):
  608. try:
  609. res1 = requests.get('http://rtsp.zositech.com:10008/api/v1/players', timeout=5)
  610. except Exception as e:
  611. res1 = -1
  612. time1 = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
  613. print("时间1:%s" % time1)
  614. # ---------压测接口demo------------
  615. redisObj = RedisObject(db=1)
  616. key1 = 'rtsp.zositech.com'
  617. key2 = '18.222.107.129'
  618. redis_data1 = redisObj.get_data(key1)
  619. redis_data2 = redisObj.get_data(key2)
  620. if redis_data1 and redis_data2:
  621. print("进缓存")
  622. mm = min(redis_data1, redis_data2)
  623. if redis_data1 == mm and redis_data1 != -1:
  624. RESP_SERVER_DOMAIN = RESP_SERVER_DOMAIN_DATA['EN']
  625. elif redis_data2 == mm and redis_data2 != -1:
  626. RESP_SERVER_DOMAIN = RESP_SERVER_DOMAIN_DATA['EN1']
  627. # ---------/压测demo------------
  628. # else:
  629. # print("第一次")
  630. # res1 = requests.get('http://rtsp.zositech.com:10008/api/v1/players', timeout=0.001)
  631. # res2 = requests.get('http://18.222.107.129:10008/api/v1/players', timeout=0.001)
  632. # res_data1 = res1.json()
  633. # res_data2 = res1.json()
  634. # total1 = res_data1['total']
  635. # total2 = res_data2['total']
  636. # print(total1)
  637. # print(total2)
  638. # redisObj8.set_data(key=key1, val=total1, expire=30)
  639. # redisObj8.set_data(key=key2, val=total2, expire=30)
  640. # mm=min(total1,total2)
  641. # print(mm)
  642. # if total1 == mm:
  643. # RESP_SERVER_DOMAIN = RESP_SERVER_DOMAIN_DATA['EN']
  644. # else:
  645. # RESP_SERVER_DOMAIN = RESP_SERVER_DOMAIN_DATA['EN1']
  646. return JsonResponse({'msg': 'The number of people online is :%s' % res1, 'code': 0})
  647. class powerController(TemplateView):
  648. def post(self, request, *args, **kwargs):
  649. request.encoding = 'utf-8'
  650. request_dict = request.POST
  651. return self.power_controller(request_dict)
  652. def get(self, request, *args, **kwargs):
  653. request.encoding = 'utf-8'
  654. request_dict = request.GET
  655. return self.power_controller(request_dict)
  656. def power_controller(self, request_dict):
  657. serial_number = request_dict.get('serial_number', '')
  658. access_token = request_dict.get('access_token', '')
  659. skill_name = request_dict.get('skill_name', 'loocam')
  660. power_controller = request_dict.get('power_controller', '')
  661. if not all([serial_number, access_token, skill_name]):
  662. return JsonResponse({'result_code': '500', '错误': '缺少参数'})
  663. user_qs = UserModel.objects.filter(access_token=access_token)
  664. if not user_qs.exists():
  665. return JsonResponse({'result_code': '500', '错误': '用户数据不存在'})
  666. userID = user_qs.first().userID
  667. switch_qs = SwitchModel.objects.filter(serial_number=serial_number, userID=userID).values('nick', 'region')
  668. if not switch_qs.exists():
  669. return JsonResponse({'result_code': '500', '错误': 'serial_number数据不存在'})
  670. logger = logging.getLogger('django')
  671. logger.info('{} 控制插座 {}'.format(skill_name, serial_number))
  672. # 请求MQTT发布消息
  673. url = '{}/api/loocam/open/socket/alexa-socket-switch'.format(SERVER_PREFIX) # 国外服务器
  674. requests_data = {'serial_number': serial_number, 'power_controller': power_controller} # TurnOn, TurnOff
  675. r = requests.post(url, requests_data)
  676. if r.status_code != 200:
  677. return JsonResponse({'result_code': '500', '错误': '请求国外服务器响应异常'})
  678. res = r.json()
  679. logger.info('国外服务器返回状态: {}'.format(res))
  680. if res['result_code'] != 0:
  681. url = '{}/api/loocam/open/socket/alexa-socket-switch'.format(SERVER_PREFIX_TEST) # 测试服务器
  682. requests_data = {'serial_number': serial_number, 'power_controller': power_controller} # TurnOn, TurnOff
  683. r = requests.post(url, requests_data)
  684. if r.status_code != 200:
  685. return JsonResponse({'result_code': '500', '错误': '请求测试服务器响应异常'})
  686. res = r.json()
  687. logger.info('测试服务器返回状态: {}'.format(res))
  688. if res['result_code'] != 0:
  689. return JsonResponse({'result_code': '500', '错误': '请求MQTT下发指令失败'})
  690. else:
  691. logger.info('请求MQTT下发指令成功')
  692. return JsonResponse({'result_code': '0'})
  693. else:
  694. logger.info('请求MQTT下发指令成功')
  695. return JsonResponse({'result_code': '0'})