water_dispenser.py 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. # -*- coding: utf-8 -*-
  2. #!/usr/bin/env python
  3. import time
  4. import logging
  5. import datetime
  6. from apilib.utils_datetime import timestamp_to_dt
  7. from apps.web.constant import Const, DeviceCmdCode, MQTT_TIMEOUT
  8. from apps.web.core.adapter.base import SmartBox, fill_2_hexByte
  9. from apps.web.core.exceptions import ServiceException
  10. from apps.web.core.networking import MessageSender
  11. from apps.web.dealer.models import Dealer
  12. from apps.web.device.models import Device, Group
  13. from apps.web.core.device_define.water_despenser import CMD_CODE
  14. from apps.web.helpers import get_wechat_manager_mp_proxy
  15. from apps.web.user.models import MyUser
  16. logger = logging.getLogger(__name__)
  17. class WaterDispenserBox(SmartBox):
  18. def __init__(self, device):
  19. super(WaterDispenserBox, self).__init__(device)
  20. def analyze_event_data(self, data):
  21. cmdCode = data[12:14]
  22. if cmdCode == CMD_CODE.WATER_DISPENSE_ALERT_EVENT_CODE:
  23. return {
  24. 'cmdCode': cmdCode,
  25. 'isError': False if data[14:16] == '00' else True,
  26. 'tempreature': int(data[16:18], 16),
  27. 'noWater': False if data[18:20] == '00' else True,
  28. 'moreWater': False if data[20:22] == '00' else True,
  29. 'port1Leak': False if data[22:24] == '00' else True,
  30. 'port2Leak': False if data[24:26] == '00' else True,
  31. 'port1Error': False if data[26:28] == '00' else True,
  32. 'port2Error': False if data[28:30] == '00' else True,
  33. 'eventKey': data[30:32],
  34. 'deviceId': data[32:36]
  35. }
  36. elif cmdCode == CMD_CODE.WATER_DISPENSE_SETTING_EVENT_CODE:
  37. return {
  38. 'cmdCode': cmdCode,
  39. 'boardSoftVer': data[24:28],
  40. }
  41. elif cmdCode == CMD_CODE.WATER_DISPENSE_WORK_STATUS_EVENT_CODE:
  42. return {
  43. 'cmdCode': cmdCode,
  44. 'port': str(int(data[14:16], 16)),
  45. 'consumeMode': data[16:18],
  46. 'isPause': data[18:20]
  47. }
  48. elif cmdCode == CMD_CODE.WATER_DISPENSE_FINISH_EVENT_CODE:
  49. port = str(int(data[14:16], 16))
  50. consumeMode = str(int(data[16:18], 16))
  51. reason = data[18:20]
  52. duration = int(data[38:42], 16)
  53. spendLitre = int(data[44:48], 16)
  54. if reason == '01':
  55. desc = u'客户停止加水'
  56. elif reason == '02':
  57. desc = u'管理员停止加水'
  58. elif reason == '03':
  59. desc = u'管理员取消'
  60. elif reason == '04':
  61. desc = u'按键终止加水'
  62. elif reason == '05':
  63. desc = u'超时终止加水'
  64. elif reason == '06':
  65. desc = u'设备故障终止加水'
  66. elif reason == '07':
  67. desc = u'加水完成'
  68. elif reason == '08':
  69. desc = u'违规使用停止加水'
  70. elif reason == '09':
  71. desc = u'套餐不符停止加水'
  72. else:
  73. desc = u'空'
  74. return {'port': port, 'cmdCode': cmdCode, 'consumeMode': consumeMode, 'reason': reason, 'desc': desc, 'duration': duration, 'spendLitre': spendLitre}
  75. def init_dev_settings(self, boardSoftVer):
  76. deviceId = self.get_device_id()
  77. device = Device.objects(devNo=self._device['devNo']).first()
  78. workMode = device.otherConf.get('workMode', '1')
  79. maxDuration = fill_2_hexByte(hex(int(device.otherConf.get('maxDuration', 60))), 2)
  80. minConsumeRatio = device.otherConf.get('minConsumeRatio', 100)
  81. pauseTime = fill_2_hexByte(hex(int(device.otherConf.get('pauseTime', 60))), 2)
  82. flowTimes = fill_2_hexByte(hex(int(device.otherConf.get('flowTimes', 1))), 4)
  83. adStartTime = device.otherConf.get('adStartTime', '19:00')
  84. nightVolume = fill_2_hexByte(hex(int(device.otherConf.get('nightVolume', 3))), 2)
  85. adEndTime = device.otherConf.get('adEndTime', '7:00')
  86. dayVolume = fill_2_hexByte(hex(int(device.otherConf.get('dayVolume', 7))), 2)
  87. adStartHours = fill_2_hexByte(hex(int(adStartTime.split(':')[0])), 2)
  88. adStartMinutes = fill_2_hexByte(hex(int(adStartTime.split(':')[1])), 2)
  89. adEndHours = fill_2_hexByte(hex(int(adEndTime.split(':')[0])), 2)
  90. adEndMinutes = fill_2_hexByte(hex(int(adEndTime.split(':')[1])), 2)
  91. firstStartCode = '00'
  92. ctrlInfo = Device.get_dev_control_cache(self._device['devNo'])
  93. if ctrlInfo.get('1', None) is not None and ctrlInfo.get('2', None) is not None:
  94. port1Error = u'电磁阀故障' in ctrlInfo['1'].get('statusErrorInfo', '')
  95. port2Error = u'电磁阀故障' in ctrlInfo['2'].get('statusErrorInfo', '')
  96. if port1Error:
  97. firstStartCode = '01'
  98. if port2Error:
  99. firstStartCode = '02'
  100. if port1Error and port2Error:
  101. firstStartCode = '03'
  102. data = '02' + maxDuration + pauseTime + flowTimes + boardSoftVer + '00' + firstStartCode + deviceId + adStartHours + adStartMinutes + nightVolume + adEndHours + adEndMinutes + dayVolume
  103. MessageSender.send(
  104. self.device,
  105. DeviceCmdCode.OPERATE_DEV_NO_RESPONSE,
  106. {'IMEI': self._device['devNo'], "funCode": "06", 'data': data},
  107. timeout=MQTT_TIMEOUT.CHECK_DEVICE_STATUS
  108. )
  109. tempAdStartHours = str(int(adStartHours, 16))
  110. tempAdStartMinutes = str(int(adStartMinutes, 16))
  111. tempAdEndHours = str(int(adEndHours, 16))
  112. tempAdEndMinutes = str(int(adEndMinutes, 16))
  113. adStartTime = '{}{}:{}{}'.format('0' if len(tempAdStartHours) == 1 else '', tempAdStartHours,
  114. '0' if len(tempAdStartMinutes) == 1 else '', tempAdStartMinutes)
  115. adEndTime = '{}{}:{}{}'.format('0' if len(tempAdEndHours) == 1 else '', tempAdEndHours,
  116. '0' if len(tempAdEndMinutes) == 1 else '', tempAdEndMinutes)
  117. device.otherConf.update({
  118. 'workMode': workMode,
  119. 'maxDuration': int(maxDuration, 16),
  120. 'minConsumeRatio': minConsumeRatio,
  121. 'pauseTime': int(pauseTime, 16),
  122. 'flowTimes': int(flowTimes, 16),
  123. 'adStartTime': adStartTime,
  124. 'nightVolume': int(nightVolume, 16),
  125. 'adEndTime': adEndTime,
  126. 'dayVolume': int(dayVolume, 16),
  127. 'boardSoftVer': boardSoftVer,
  128. 'clearFault': 0
  129. })
  130. device.save()
  131. Device.invalid_device_cache(device.devNo)
  132. def get_device_id(self):
  133. devNo = self._device['devNo']
  134. deviceId = Device.get_dev_control_cache(devNo).get('deviceId', '')
  135. if deviceId == '':
  136. raise ServiceException({'result': 2, 'description': u'未获取到设备ID,设备故障,请联系经销商'})
  137. return deviceId
  138. def get_port_status_from_dev(self): # 获取端口状态, 播放语音
  139. deviceId = self.get_device_id()
  140. # TODO 目前只有一种语音类型,后续业务完成后,增加警告以及拒绝的语音类型。
  141. voiceType = '01'
  142. orderNo = '000000000000'
  143. data = '00' + voiceType + '00' + orderNo + deviceId + '000000' + '000000'
  144. devInfo = MessageSender.send(
  145. self.device,
  146. self.make_random_cmdcode(),
  147. {'IMEI': self._device['devNo'], "funCode": "04", 'data': data},
  148. timeout=MQTT_TIMEOUT.CHECK_DEVICE_STATUS
  149. )
  150. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  151. if devInfo['rst'] == -1:
  152. raise ServiceException(
  153. {'result': 2, 'description': u'当前设备正在玩命找网络,请您稍候再试'})
  154. elif devInfo['rst'] == 1:
  155. raise ServiceException(
  156. {'result': 2, 'description': u'当前设备忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})
  157. portStatus = devInfo['data'][18:20]
  158. if portStatus == '00':
  159. result = {'1':{'status': Const.DEV_WORK_STATUS_IDLE}, '2':{'status': Const.DEV_WORK_STATUS_IDLE}}
  160. elif portStatus == '01':
  161. result = {'1': {'status': Const.DEV_WORK_STATUS_IDLE}, '2': {'status': Const.DEV_WORK_STATUS_WORKING}}
  162. elif portStatus == '02':
  163. result = {'1': {'status': Const.DEV_WORK_STATUS_IDLE}, '2': {'status': Const.DEV_WORK_STATUS_FAULT}}
  164. elif portStatus == '03':
  165. result = {'1': {'status': Const.DEV_WORK_STATUS_WORKING}, '2': {'status': Const.DEV_WORK_STATUS_IDLE}}
  166. elif portStatus == '04':
  167. result = {'1': {'status': Const.DEV_WORK_STATUS_FAULT}, '2': {'status': Const.DEV_WORK_STATUS_IDLE}}
  168. elif portStatus == '05':
  169. result = {'1': {'status': Const.DEV_WORK_STATUS_WORKING}, '2': {'status': Const.DEV_WORK_STATUS_WORKING}}
  170. elif portStatus == '07':
  171. result = {'1': {'status': Const.DEV_WORK_STATUS_FAULT}, '2': {'status': Const.DEV_WORK_STATUS_WORKING}}
  172. elif portStatus == '08':
  173. result = {'1': {'status': Const.DEV_WORK_STATUS_WORKING}, '2': {'status': Const.DEV_WORK_STATUS_FAULT}}
  174. else:
  175. result = {'1': {'status': Const.DEV_WORK_STATUS_FAULT}, '2': {'status': Const.DEV_WORK_STATUS_FAULT}}
  176. allPorts, usedPorts, usePorts = self.get_port_static_info(result)
  177. Device.update_dev_control_cache(self._device['devNo'],
  178. {'allPorts': allPorts, 'usedPorts': usedPorts, 'usePorts': usePorts})
  179. # 这里存在多线程更新缓存的场景,可能性比较低,但是必须先取出来,然后逐个更新状态,然后再记录缓存
  180. ctrInfo = Device.get_dev_control_cache(self._device['devNo'])
  181. for strPort, info in result.items():
  182. if ctrInfo.has_key(strPort):
  183. ctrInfo[strPort].update({'status': info['status']})
  184. else:
  185. ctrInfo[strPort] = info
  186. Device.update_dev_control_cache(self._device['devNo'], ctrInfo)
  187. return result
  188. def get_port_status(self, force=True):
  189. return self.get_port_status_from_dev()
  190. def start_device(self, package, openId, attachParas):
  191. if attachParas is None:
  192. raise ServiceException({'result': 2, 'description': u'请您选择合适的充电线路、电池类型信息'})
  193. if not attachParas.has_key('chargeIndex'):
  194. raise ServiceException({'result': 2, 'description': u'请您选择合适的充电线路'})
  195. device = Device.objects(devNo=self._device['devNo']).first()
  196. port = '0' + attachParas['chargeIndex']
  197. workMode = device.otherConf.get('workMode', '1')
  198. hexWorkMode = fill_2_hexByte(hex(int(workMode)), 2)
  199. orderNo = '000000000000'
  200. deviceId = self.get_device_id()
  201. agentId = Dealer.objects(id=device.ownerId).first().agentId
  202. # 同步用户
  203. users = MyUser.objects(openId=openId, agentId=agentId)
  204. breakRuleTimesList = []
  205. voiceType = '00'
  206. for _ in users:
  207. breakRuleTimesList.append(_.blacklistConfig.get('breakRuleTimes', 0))
  208. if 1 in breakRuleTimesList:
  209. for u in users:
  210. u.blacklistConfig['breakRuleTimes'] = 1
  211. u.blacklistConfig['orderRemindType'] = 0
  212. u.save()
  213. voiceType = '02'
  214. if 2 in breakRuleTimesList:
  215. for u in users:
  216. u.blacklistConfig['breakRuleTimes'] = 2
  217. u.blacklistConfig['orderRemindType'] = 0
  218. u.save()
  219. voiceType = '03'
  220. # 播放不同语音
  221. vData = '00' + voiceType + '00' + orderNo + deviceId + '000000' + '000000'
  222. devInfo = MessageSender.send(
  223. self.device,
  224. self.make_random_cmdcode(),
  225. {'IMEI': self._device['devNo'], "funCode": "04", 'data': vData},
  226. timeout=MQTT_TIMEOUT.CHECK_DEVICE_STATUS
  227. )
  228. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  229. if devInfo['rst'] == -1:
  230. raise ServiceException(
  231. {'result': 2, 'description': u'当前设备正在玩命找网络,请您稍候再试'})
  232. elif devInfo['rst'] == 1:
  233. raise ServiceException(
  234. {'result': 2, 'description': u'当前设备忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})
  235. # 黑名单用户跳出
  236. if voiceType == '03':
  237. raise ServiceException({'result': 2, 'description': u'黑名单用户,拒绝提供服务。'})
  238. price = float(package['price'])
  239. coins = float(package['coins'])
  240. needTime = 0
  241. needLitre = 0
  242. unit = package['unit']
  243. if unit in [u'升', u'毫升']:
  244. needLitre = int(package['time'])
  245. hexLitre = fill_2_hexByte(hex(needLitre))
  246. hexTime = '0000'
  247. consumeMode = '2'
  248. hexConsumeMode = '02'
  249. elif unit == u'秒':
  250. needTime = int(package['time'])
  251. hexTime = fill_2_hexByte(hex(needTime))
  252. hexLitre = '0000'
  253. consumeMode = '1'
  254. hexConsumeMode = '01'
  255. else:
  256. raise ServiceException({'result': 2, 'description': u'套餐单位错误,请重新设置'})
  257. data = port + hexConsumeMode + hexWorkMode + orderNo + deviceId + '00' + hexTime + '00' + hexLitre
  258. devInfo = MessageSender.send(
  259. device = self.device,
  260. cmd = DeviceCmdCode.OPERATE_DEV_SYNC,
  261. payload = {
  262. 'IMEI': self._device['devNo'],
  263. "funCode": "01",
  264. 'data': data
  265. }, timeout = MQTT_TIMEOUT.START_DEVICE)
  266. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  267. if devInfo['rst'] == -1:
  268. raise ServiceException(
  269. {'result': 2, 'description': u'当前设备正在玩命找网络,您的金币还在,重试不需要重新付款,建议您试试旁边其他设备,或者稍后再试哦'})
  270. elif devInfo['rst'] == 1:
  271. raise ServiceException({'result': 2, 'description': u'当前设备正在忙,无响应,您的金币还在,请试试其他线路,或者请稍后再试哦'})
  272. result = devInfo['data'][14::]
  273. resultPort = int(result[0:2], 16)
  274. resultStatus = data[4:6]
  275. if resultStatus == '02': # 代表失败
  276. raise ServiceException({'result': 2, 'description': u'设备正在工作中,不能重复启动。'})
  277. start_timestamp = int(time.time())
  278. portDict = {
  279. 'startTime': timestamp_to_dt(start_timestamp).strftime('%Y-%m-%d %H:%M:%S'),
  280. 'status': Const.DEV_WORK_STATUS_WORKING,
  281. 'price': price,
  282. 'coins': coins,
  283. 'isStart': True,
  284. 'needTime': needTime,
  285. 'needLitre': needLitre,
  286. 'consumeMode':consumeMode,
  287. 'workMode': workMode,
  288. 'openId': openId,
  289. 'refunded': False,
  290. 'vCardId': self._vcard_id
  291. }
  292. if 'linkedRechargeRecordId' in attachParas and attachParas.get('isQuickPay', False):
  293. item = {
  294. 'rechargeRcdId': str(attachParas['linkedRechargeRecordId'])
  295. }
  296. payInfo = list()
  297. payInfo.append(item)
  298. portDict['payInfo'] = payInfo
  299. Device.update_dev_control_cache(self._device['devNo'], {str(resultPort): portDict})
  300. # 推送的首要判断条件是用户是属于哪一类用户
  301. user = MyUser.objects(openId=openId, groupId=self._device['groupId']).first()
  302. if user.is_push_live(float(str(price)), float(device.otherConf.get('liveLimitedPrice', '0.0'))) is True:
  303. group = Group.objects(id=device.groupId).first()
  304. dealer = Dealer.objects(id=device.ownerId).first()
  305. liveUrl = device.otherConf.get('liveUrl', 'https://open.ys7.com/view/h5/942c931863f04fddb9c9411a1a95a818')
  306. wechat_mp_proxy = get_wechat_manager_mp_proxy(dealer)
  307. wechat_mp_proxy.notify(
  308. dealer.managerialOpenId or '',
  309. 'dev_start',
  310. liveUrl,
  311. **{
  312. 'title': u'{}'.format(group.groupName),
  313. 'things': u'加水机设备{}正在使用!\\n'.format(device.logicalCode),
  314. 'time': datetime.datetime.now().strftime(Const.DATETIME_FMT),
  315. 'remark': liveUrl
  316. })
  317. return devInfo
  318. def lock_unlock_port(self, port, lock = True):
  319. if port == 1:
  320. lockStr = '04' if lock else '02'
  321. elif port == 2:
  322. lockStr = '05' if lock else '03'
  323. else:
  324. raise ServiceException({'result': 2, 'description': u'系统异常'})
  325. deviceId = self.get_device_id()
  326. data = '02' + '00' + '00' + '0000' + '0000' + lockStr + '00' + deviceId + '00' + '00' + '00' + '00' + '00' + '00'
  327. devInfo = MessageSender.send(
  328. self.device,
  329. DeviceCmdCode.OPERATE_DEV_SYNC,
  330. {'IMEI': self._device['devNo'], "funCode": "05", 'data': data}
  331. )
  332. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  333. if devInfo['rst'] == -1:
  334. raise ServiceException(
  335. {'result': 2, 'description': u'当前设备正在玩命找网络,您的金币还在,重试不需要重新付款,建议您试试旁边其他设备,或者稍后再试哦'})
  336. elif devInfo['rst'] == 1:
  337. raise ServiceException({'result': 2, 'description': u'当前设备正在忙,无响应,您的金币还在,请试试其他线路,或者请稍后再试哦'})
  338. if devInfo['data'][28:30] == '06':
  339. raise ServiceException({'result': 2, 'description': u'操作端口失败,繁忙中禁用'})
  340. if lock:
  341. Device.update_dev_control_cache(self._device['devNo'],
  342. {str(port): {'status': Const.DEV_WORK_STATUS_FORBIDDEN}})
  343. else:
  344. Device.update_dev_control_cache(self._device['devNo'], {str(port): {'status': Const.DEV_WORK_STATUS_IDLE}})
  345. def stop(self, port = None):
  346. infoDict = self.stop_charging_port(port)
  347. infoDict['remainder_time'] = 0
  348. return infoDict
  349. def active_deactive_port(self, port, active):
  350. if not active:
  351. self.stop_charging_port(port)
  352. devInfo = Device.get_dev_control_cache(self._device['devNo'])
  353. portCtrInfo = devInfo.get(str(port), {})
  354. portCtrInfo.update({'isStart': False, 'status': Const.DEV_WORK_STATUS_IDLE,
  355. 'endTime': datetime.datetime.now().strftime(Const.DATETIME_FMT)})
  356. newValue = {str(port): portCtrInfo}
  357. Device.update_dev_control_cache(self._device['devNo'], newValue)
  358. else:
  359. raise ServiceException({'result': 2, 'description': u'此设备不支持直接打开端口'})
  360. def stop_charging_port(self, port):
  361. portStr = fill_2_hexByte(hex(int(port)), 2)
  362. lineInfo = Device.get_dev_control_cache(self.device['devNo'])[str(port)]
  363. consumeMode = lineInfo.get('consumeMode', '1')
  364. hexConsumeMode = fill_2_hexByte(hex(int(consumeMode)), 2)
  365. stopType = lineInfo.get('stopType', '000002')
  366. if stopType == 'dealerStopUsingPort':
  367. stopType = '000002'
  368. elif stopType == 'dealerCancelOrder':
  369. stopType = '000003'
  370. elif stopType == 'illegalUseStop':
  371. stopType = '000004'
  372. elif stopType == 'packageMismatchStop':
  373. stopType = '000005'
  374. else:
  375. stopType = '000001'
  376. deviceId = self.get_device_id()
  377. data = portStr + hexConsumeMode + '00' + '000000000000' + deviceId + stopType + '000000'
  378. devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
  379. {'IMEI': self._device['devNo'], "funCode": "02", 'data': data})
  380. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  381. if devInfo['rst'] == -1:
  382. raise ServiceException(
  383. {'result': 2, 'description': u'充电桩正在玩命找网络,请您稍候再试'})
  384. elif devInfo['rst'] == 1:
  385. raise ServiceException(
  386. {'result': 2, 'description': u'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})
  387. result = devInfo['data'][36:42]
  388. if result == '000006':
  389. raise ServiceException({'result': 2, 'description': u'设备正在工作中,不能重复启动。'})
  390. return {}
  391. def pauseToUseDevice(self, port, oper):
  392. lineInfo = Device.get_dev_control_cache(self._device['devNo'])
  393. isPause = lineInfo[str(port)].get('isPause', False)
  394. PauseCode = '01' if isPause is False else '02'
  395. consumeMode = lineInfo[str(port)].get('consumeMode', '1')
  396. hexConsumeMode = fill_2_hexByte(hex(int(consumeMode)), 2)
  397. orderNo = '000000000000'
  398. deviceId = self.get_device_id()
  399. pauseType = '000001'
  400. hexPort = fill_2_hexByte(hex(int(port)), 2)
  401. data = hexPort + hexConsumeMode + PauseCode + orderNo + deviceId + pauseType + '000000'
  402. devInfo = MessageSender.send(
  403. self.device,
  404. DeviceCmdCode.OPERATE_DEV_SYNC,
  405. {'IMEI': self._device['devNo'], "funCode": "03", 'data': data}
  406. )
  407. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  408. if devInfo['rst'] == -1:
  409. raise ServiceException(
  410. {'result': 2, 'description': u'当前设备正在玩命找网络,您的金币还在,重试不需要重新付款,建议您试试旁边其他设备,或者稍后再试哦'})
  411. elif devInfo['rst'] == 1:
  412. raise ServiceException({'result': 2, 'description': u'当前设备正在忙,无响应,您的金币还在,请试试其他线路,或者请稍后再试哦'})
  413. devInfoData = devInfo['data']
  414. result = devInfoData[18:20]
  415. if result == '03':
  416. raise ServiceException({'result': 2, 'description': u'操作失败,请重试'})
  417. def get_dev_setting(self):
  418. data = '03' + '00000000000000000000000000000000'
  419. devInfo = MessageSender.send(
  420. self.device,
  421. DeviceCmdCode.OPERATE_DEV_SYNC,
  422. {'IMEI': self._device['devNo'], "funCode": "06", 'data': data}
  423. )
  424. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  425. if devInfo['rst'] == -1:
  426. raise ServiceException(
  427. {'result': 2, 'description': u'当前设备正在玩命找网络,您的金币还在,重试不需要重新付款,建议您试试旁边其他设备,或者稍后再试哦'})
  428. elif devInfo['rst'] == 1:
  429. raise ServiceException({'result': 2, 'description': u'当前设备正在忙,无响应,您的金币还在,请试试其他线路,或者请稍后再试哦'})
  430. devInfoData = devInfo['data']
  431. if devInfoData[14:16] != '04':
  432. raise ServiceException({'result': 2, 'description': u'获取参数失败,系统异常'})
  433. maxDuration = int(devInfoData[16:18], 16)
  434. pauseTime = int(devInfoData[18:20], 16)
  435. flowTimes = int(devInfoData[20:24], 16)
  436. boardSoftVer = devInfoData[24:28]
  437. adStartHours = str(int(devInfoData[36:38], 16))
  438. adStartMinutes = str(int(devInfoData[38:40], 16))
  439. nightVolume = int(devInfoData[40:42], 16)
  440. adEndHours = str(int(devInfoData[42:44], 16))
  441. adEndMinutes = str(int(devInfoData[44:46], 16))
  442. dayVolume = int(devInfoData[46:48], 16)
  443. adStartTime = '{}{}:{}{}'.format('0' if len(adStartHours) == 1 else '', adStartHours, '0' if len(adStartMinutes) == 1 else '', adStartMinutes)
  444. adEndTime = '{}{}:{}{}'.format('0' if len(adEndHours) == 1 else '', adEndHours, '0' if len(adEndMinutes) == 1 else '', adEndMinutes)
  445. device = Device.objects(devNo=self._device['devNo']).first()
  446. device.otherConf.update({
  447. 'maxDuration': maxDuration,
  448. 'pauseTime': pauseTime,
  449. 'flowTimes': flowTimes,
  450. 'boardSoftVer': boardSoftVer,
  451. 'adStartTime': adStartTime,
  452. 'nightVolume': nightVolume,
  453. 'adEndTime': adEndTime,
  454. 'dayVolume': dayVolume,
  455. })
  456. device.save()
  457. Device.invalid_device_cache(device.devNo)
  458. clearFault = device.otherConf.get('clearFault', 0)
  459. workMode = device.otherConf.get('workMode', '1')
  460. minConsumeRatio = device.otherConf.get('minConsumeRatio', 5)
  461. return {
  462. 'maxDuration': maxDuration,
  463. 'pauseTime': pauseTime,
  464. 'flowTimes': flowTimes,
  465. 'boardSoftVer': boardSoftVer,
  466. 'adStartTime': adStartTime,
  467. 'nightVolume': nightVolume,
  468. 'adEndTime': adEndTime,
  469. 'dayVolume': dayVolume,
  470. 'clearFault': clearFault,
  471. 'workMode': workMode,
  472. 'minConsumeRatio': minConsumeRatio
  473. }
  474. def set_device_function_param(self, request, lastSetConf):
  475. tempSetConf = {}
  476. if 'maxDuration' in request.POST:
  477. maxDuration = request.POST['maxDuration']
  478. pauseTime = request.POST['pauseTime']
  479. minConsumeRatio = request.POST['minConsumeRatio']
  480. boardSoftVer = request.POST['boardSoftVer']
  481. flowTimes = request.POST['flowTimes']
  482. workMode = request.POST['workMode']
  483. clearFault = 0
  484. tempSetConf.update({
  485. 'maxDuration': maxDuration,
  486. 'pauseTime': pauseTime,
  487. 'minConsumeRatio': minConsumeRatio,
  488. 'boardSoftVer': boardSoftVer,
  489. 'flowTimes': flowTimes,
  490. 'workMode': workMode,
  491. 'clearFault': clearFault
  492. })
  493. self.set_dev_setting(tempSetConf)
  494. elif 'adStartTime' in request.POST:
  495. adStartTime = request.POST['adStartTime']
  496. adEndTime = request.POST['adEndTime']
  497. dayVolume = request.POST['dayVolume']
  498. nightVolume = request.POST['nightVolume']
  499. adStartHours = str(int(adStartTime.split(':')[0]))
  500. adStartMinutes = str(int(adStartTime.split(':')[1]))
  501. adEndHours = str(int(adEndTime.split(':')[0]))
  502. adEndMinutes = str(int(adEndTime.split(':')[1]))
  503. tempSetConf.update({
  504. 'dayVolume': dayVolume,
  505. 'nightVolume': nightVolume,
  506. 'adStartHours': adStartHours,
  507. 'adStartMinutes': adStartMinutes,
  508. 'adEndHours': adEndHours,
  509. 'adEndMinutes': adEndMinutes
  510. })
  511. self.set_dev_setting(tempSetConf)
  512. def set_dev_setting(self, setConf):
  513. maxDuration = pauseTime = flowTimes = boardSoftVer = clearFault = adStartHours = adStartMinutes = nightVolume = adEndHours = adEndMinutes = dayVolume = '00'
  514. if 'maxDuration' in setConf:
  515. maxDuration = fill_2_hexByte(hex(int(setConf['maxDuration'])), 2)
  516. pauseTime = fill_2_hexByte(hex(int(setConf['pauseTime'])), 2)
  517. flowTimes = fill_2_hexByte(hex(int(setConf['flowTimes'])), 4)
  518. boardSoftVer = setConf['boardSoftVer']
  519. clearFault = fill_2_hexByte(hex(int(setConf['clearFault'])), 2)
  520. setType = '03'
  521. elif 'adStartHours' in setConf:
  522. adStartHours = fill_2_hexByte(hex(int(setConf['adStartHours'])), 2)
  523. adStartMinutes = fill_2_hexByte(hex(int(setConf['adStartMinutes'])), 2)
  524. nightVolume = fill_2_hexByte(hex(int(setConf['nightVolume'])), 2)
  525. adEndHours = fill_2_hexByte(hex(int(setConf['adEndHours'])), 2)
  526. adEndMinutes = fill_2_hexByte(hex(int(setConf['adEndMinutes'])), 2)
  527. dayVolume = fill_2_hexByte(hex(int(setConf['dayVolume'])), 2)
  528. setType = '01'
  529. else:
  530. raise ServiceException({'result': 2, 'description': u'参数判断错误'})
  531. deviceId = self.get_device_id()
  532. if setType == '03':
  533. data = setType + maxDuration + pauseTime + flowTimes + boardSoftVer + clearFault + '00' + deviceId + '00' + '00' + '00' + '00' + '00' + '00'
  534. else:
  535. data = setType + '00' + '00' + '0000' + '0000' + '00' + '00' + deviceId + adStartHours + adStartMinutes + nightVolume + adEndHours + adEndMinutes + dayVolume
  536. devInfo = MessageSender.send(
  537. self.device,
  538. DeviceCmdCode.OPERATE_DEV_SYNC,
  539. {'IMEI': self._device['devNo'], "funCode": "05", 'data': data}
  540. )
  541. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  542. if devInfo['rst'] == -1:
  543. raise ServiceException(
  544. {'result': 2, 'description': u'当前设备正在玩命找网络,您的金币还在,重试不需要重新付款,建议您试试旁边其他设备,或者稍后再试哦'})
  545. elif devInfo['rst'] == 1:
  546. raise ServiceException({'result': 2, 'description': u'当前设备正在忙,无响应,您的金币还在,请试试其他线路,或者请稍后再试哦'})
  547. if devInfo['data'][14:16] == '04':
  548. raise ServiceException({'result': 2, 'description': u'参数修改失败,运行中和暂停中修改参数'})
  549. device = Device.objects(devNo=self._device['devNo']).first()
  550. if setType == '03':
  551. device.otherConf.update({
  552. 'maxDuration': int(maxDuration, 16),
  553. 'pauseTime': int(pauseTime, 16),
  554. 'flowTimes': int(flowTimes, 16),
  555. 'boardSoftVer': boardSoftVer,
  556. 'workMode': setConf['workMode'],
  557. 'minConsumeRatio': int(setConf['minConsumeRatio']),
  558. 'clearFault': 0
  559. })
  560. else:
  561. tempAdStartHours = str(int(adStartHours, 16))
  562. tempAdStartMinutes = str(int(adStartMinutes, 16))
  563. tempAdEndHours = str(int(adEndHours, 16))
  564. tempAdEndMinutes = str(int(adEndMinutes, 16))
  565. adStartTime = '{}{}:{}{}'.format('0' if len(tempAdStartHours) == 1 else '', tempAdStartHours, '0' if len(tempAdStartMinutes) == 1 else '', tempAdStartMinutes)
  566. adEndTime = '{}{}:{}{}'.format('0' if len(tempAdEndHours) == 1 else '', tempAdEndHours, '0' if len(tempAdEndMinutes) == 1 else '', tempAdEndMinutes)
  567. device.otherConf.update({
  568. 'adStartTime': adStartTime,
  569. 'adEndTime': adEndTime,
  570. 'nightVolume': int(nightVolume, 16),
  571. 'dayVolume': int(dayVolume, 16),
  572. })
  573. device.save()
  574. Device.invalid_device_cache(device.devNo)