sijiang.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  1. # -*- coding: utf-8 -*-
  2. # !/usr/bin/env python
  3. import datetime
  4. import logging
  5. from django.core.cache import caches
  6. from typing import Dict, Optional
  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.device.models import Device
  12. from apps.web.api.models import APIStartDeviceRecord
  13. logger = logging.getLogger(__name__)
  14. class ChargingSiJiangBox(SmartBox):
  15. def __init__(self, device):
  16. super(ChargingSiJiangBox, self).__init__(device)
  17. def translate_funcode(self, funCode):
  18. funCodeDict = {
  19. '01': u'获取端口数量',
  20. '02': u'移动支付',
  21. '0C': u'获取设备设置',
  22. '08': u'设置设备参数',
  23. '06': u'获取设备端口详情',
  24. '07': u'获取刷卡投币统计数据',
  25. '09': u'设置刷卡投币使能',
  26. '0A': u'端口使能',
  27. '0B': u'端口关闭',
  28. '16': u'设置设备参数',
  29. '20': u'设备重启',
  30. }
  31. return funCodeDict.get(funCode, '')
  32. def translate_event_cmdcode(self, cmdCode):
  33. cmdDict = {
  34. '03': u'投币上报',
  35. '04': u'刷卡上报',
  36. '05': u'充电结束',
  37. '10': u'刷卡上报',
  38. '0D': u'故障',
  39. }
  40. return cmdDict.get(cmdCode, '')
  41. # 获取端口状态(缓存)
  42. def get_port_status(self, force = False):
  43. if force:
  44. return self.get_port_status_from_dev()
  45. ctrInfo = Device.get_dev_control_cache(self._device['devNo'])
  46. statusDict = {}
  47. staticPorts = self.get_port_number_from_type_code()
  48. allPorts = ctrInfo.get('allPorts', staticPorts)
  49. # allPorts 有的时候会为0, 这个时候强制设置为设备类型CODE对应的字段
  50. if allPorts == 0:
  51. allPorts = staticPorts
  52. for ii in range(allPorts):
  53. tempDict = ctrInfo.get(str(ii), {})
  54. if tempDict.has_key('status'):
  55. statusDict[str(ii)] = {'status': tempDict.get('status')}
  56. elif tempDict.has_key('isStart'):
  57. if tempDict['isStart']:
  58. statusDict[str(ii)] = {'status': Const.DEV_WORK_STATUS_WORKING}
  59. else:
  60. statusDict[str(ii)] = {'status': Const.DEV_WORK_STATUS_IDLE}
  61. else:
  62. statusDict[str(ii)] = {'status': Const.DEV_WORK_STATUS_IDLE}
  63. allPorts, usedPorts, usePorts = self.get_port_static_info(statusDict)
  64. Device.update_dev_control_cache(self._device['devNo'],
  65. {'allPorts': allPorts, 'usedPorts': usedPorts, 'usePorts': usePorts})
  66. return statusDict
  67. # 获取端口状态
  68. def get_port_status_from_dev(self):
  69. devInfo = MessageSender.send(self.device, self.make_random_cmdcode(),
  70. {'IMEI': self._device['devNo'], "funCode": '01', 'data': '00'})
  71. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  72. if devInfo['rst'] == -1:
  73. raise ServiceException(
  74. {'result': 2, 'description': u'充电桩正在玩命找网络,请您稍候再试'})
  75. elif devInfo['rst'] == 1:
  76. raise ServiceException(
  77. {'result': 2, 'description': u'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})
  78. data = devInfo['data'][6::]
  79. result = {}
  80. portNum = int(data[0:2], 16)
  81. portData = data[2::]
  82. ii = 0
  83. while ii < portNum:
  84. port = ii
  85. statusTemp = portData[ii * 2 : ii * 2 + 2]
  86. if statusTemp == '01':
  87. status = {'status': Const.DEV_WORK_STATUS_IDLE}
  88. elif statusTemp == '02':
  89. status = {'status': Const.DEV_WORK_STATUS_WORKING}
  90. elif statusTemp == '03':
  91. status = {'status': Const.DEV_WORK_STATUS_FORBIDDEN}
  92. elif statusTemp == '04':
  93. status = {'status': Const.DEV_WORK_STATUS_FAULT}
  94. else:
  95. raise ServiceException({'result': 2, 'description': u'数据有误'})
  96. ii += 1
  97. result[str(port)] = status
  98. allPorts, usedPorts, usePorts = self.get_port_static_info(result)
  99. Device.update_dev_control_cache(self._device['devNo'],
  100. {'allPorts': allPorts, 'usedPorts': usedPorts, 'usePorts': usePorts})
  101. # 这里存在多线程更新缓存的场景,可能性比较低,但是必须先取出来,然后逐个更新状态,然后再记录缓存
  102. ctrInfo = Device.get_dev_control_cache(self._device['devNo'])
  103. for strPort, info in result.items():
  104. if ctrInfo.has_key(strPort):
  105. ctrInfo[strPort].update({'status': info['status']})
  106. else:
  107. ctrInfo[strPort] = info
  108. Device.update_dev_control_cache(self._device['devNo'], ctrInfo)
  109. return result
  110. def test(self, coins):
  111. package = {
  112. 'unit': u'分钟',
  113. 'time': 5,
  114. 'coins': 1,
  115. 'price': 1
  116. }
  117. return self.start_device(package = package, openId = 'tester', attachParas = {'chargeIndex': 0})
  118. def start_device(self, package, openId, attachParas):
  119. # type: (Dict, str, Dict)->Dict
  120. if attachParas is None:
  121. raise ServiceException({'result': 2, 'description': u'请您选择合适的充电线路、电池类型信息'})
  122. if 'chargeIndex' not in attachParas:
  123. raise ServiceException({'result': 2, 'description': u'请您选择合适的充电线路(端口)'})
  124. devConf = caches['devmgr'].get('settingConf_%s' % (self._device['devNo']))
  125. if devConf is None:
  126. conf = self.get_dev_setting()
  127. caches['devmgr'].set('settingConf_%s' % (self._device['devNo']), conf, 24 * 3600)
  128. # 从0改为1
  129. port = hex(int(attachParas['chargeIndex']) + 1)
  130. hexPort = fill_2_hexByte(port, 2)
  131. needTime = int(package['time'])
  132. needCoins = int(package['coins'])
  133. money = package['price']
  134. unit = package.get('unit', u'分钟')
  135. if unit == u'小时':
  136. needTime = int(package['time']) * 60
  137. elif unit == u'天':
  138. needTime = int(package['time']) * 1440
  139. hexTime = fill_2_hexByte(hex(needTime))
  140. devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
  141. {'IMEI': self._device['devNo'], "funCode": '02',
  142. 'data': hexPort + hexTime}, timeout = MQTT_TIMEOUT.START_DEVICE)
  143. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  144. if devInfo['rst'] == -1:
  145. raise ServiceException({'result': 2, 'description': u'充电桩正在玩命找网络,您的金币还在,重试不需要重新付款,建议您试试旁边其他设备,或者稍后再试哦'})
  146. elif devInfo['rst'] == 1:
  147. self.check_serial_port_for_startcmd(attachParas['chargeIndex'])
  148. data = devInfo['data'][6::]
  149. # 从1改为0
  150. devInfo['usePort'] = usePort = int(data[0:2], 16) - 1
  151. result = data[2:4]
  152. if result == '00': # 成功
  153. pass
  154. elif result == '02':
  155. newValue = {str(usePort): {'status': Const.DEV_WORK_STATUS_FAULT, 'statusInfo': u'充电站故障'}}
  156. Device.update_dev_control_cache(self._device['devNo'], newValue)
  157. raise ServiceException({'result': 2, 'description': u'充电站故障'})
  158. elif result == '03':
  159. newValue = {str(usePort): {'status': Const.DEV_WORK_STATUS_WORKING, 'statusInfo': u''}}
  160. Device.update_dev_control_cache(self._device['devNo'], newValue)
  161. raise ServiceException({'result': 2, 'description': u'该端口正在使用中'})
  162. portCache = Device.get_dev_control_cache(self._device['devNo']).get(str(usePort), {})
  163. update_dict = {
  164. 'money': money,
  165. 'status': Const.DEV_WORK_STATUS_WORKING,
  166. 'isStart': True,
  167. 'openId': openId,
  168. 'refunded': False,
  169. }
  170. if portCache.get('status') == Const.DEV_WORK_STATUS_WORKING and portCache.get('openId') == openId:
  171. update_dict['coins'] = portCache.get('coins', 0) + needCoins
  172. update_dict['needTime'] = portCache['needTime'] + needTime
  173. update_dict['startTime'] = portCache['startTime']
  174. is_continus = True
  175. else:
  176. update_dict['coins'] = needCoins
  177. update_dict['needTime'] = needTime
  178. update_dict['startTime'] = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  179. update_dict['vCardId'] = self._vcard_id
  180. is_continus = False
  181. if 'linkedRechargeRecordId' in attachParas and attachParas.get('isQuickPay', False):
  182. item = {
  183. 'rechargeRcdId': str(attachParas['linkedRechargeRecordId'])
  184. }
  185. if is_continus:
  186. pay_info = portCache.get('payInfo', list())
  187. else:
  188. pay_info = list()
  189. pay_info.append(item)
  190. update_dict['payInfo'] = pay_info
  191. if 'extOrderNo' in attachParas:
  192. update_dict['extOrderNo'] = attachParas.get('extOrderNo')
  193. Device.update_dev_control_cache(
  194. self._device['devNo'],
  195. {
  196. str(usePort): update_dict
  197. }
  198. )
  199. return devInfo
  200. def start_from_api(self, record):
  201. # type: (APIStartDeviceRecord)->Optional[Dict]
  202. if 'chargeIndex' not in record.attachParas:
  203. from apps.web.api.exceptions import ApiParameterError
  204. raise ApiParameterError(u'请传入充电桩端口号chargeIndex参数')
  205. return super(ChargingSiJiangBox, self).start_from_api(record)
  206. # 获取设备配置参数
  207. def get_dev_setting(self):
  208. devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
  209. {'IMEI': self._device['devNo'], "funCode": '0C', 'data': '00'})
  210. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  211. if devInfo['rst'] == -1:
  212. raise ServiceException(
  213. {'result': 2, 'description': u'充电桩正在玩命找网络,请您稍候再试'})
  214. elif devInfo['rst'] == 1:
  215. raise ServiceException(
  216. {'result': 2, 'description': u'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})
  217. confData = devInfo['data'][6:-2]
  218. icMoney = int(confData[0:2], 16) / 10
  219. icTime = int(confData[2:4], 16) * 10
  220. tbTime = int(confData[4:6], 16) * 10
  221. stdPower = int(confData[6:8], 16) * 10
  222. maxPower = int(confData[8:10], 16) * 10
  223. dataDict1 = self.get_param_setting()
  224. dataDict2 = {'icMoney': icMoney,
  225. 'icTime': icTime,
  226. 'tbTime': tbTime,
  227. 'stdPower': stdPower,
  228. 'maxPower': maxPower}
  229. dataDict3 = self.get_dev_consume_count()
  230. return dict(dataDict1.items() + dataDict2.items() + dataDict3.items())
  231. # 设置设备参数
  232. def set_dev_setting(self, setConf):
  233. data = ''
  234. data += fill_2_hexByte(hex(int(setConf['icMoney']) * 10), 2) # 这个改不了, 默认的
  235. data += fill_2_hexByte(hex(int(setConf['icTime']) / 10), 2)
  236. data += fill_2_hexByte(hex(int(setConf['tbTime']) / 10), 2)
  237. data += fill_2_hexByte(hex(int(setConf['stdPower']) / 10), 2)
  238. data += fill_2_hexByte(hex(int(setConf['maxPower']) / 10), 2)
  239. devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
  240. {'IMEI': self._device['devNo'], "funCode": '08', 'data': data})
  241. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  242. if devInfo['rst'] == -1:
  243. raise ServiceException(
  244. {'result': 2, 'description': u'充电桩正在玩命找网络,请您稍候再试'})
  245. elif devInfo['rst'] == 1:
  246. raise ServiceException(
  247. {'result': 2, 'description': u'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})
  248. # 分析事件参数
  249. def analyze_event_data(self, data):
  250. cmdCode = data[4:6]
  251. if cmdCode == '03': # 投币上报
  252. coin = int(data[6:8], 16)
  253. return {'status': Const.DEV_WORK_STATUS_IDLE, 'cmdCode': cmdCode, 'coin': coin}
  254. if cmdCode == '04': # 刷卡上报
  255. money = int(data[6:8], 16)
  256. return {'status': Const.DEV_WORK_STATUS_IDLE, 'cmdCode': cmdCode, 'money': money}
  257. if cmdCode == '05': # 提交充电结束状态
  258. # 匹配0-9
  259. port = int(data[6:8], 16) - 1
  260. leftTime = int(data[8:12], 16)
  261. finishedState = data[12:14]
  262. desc = ''
  263. if finishedState == '00':
  264. desc = u'您购买的充电时间用完了, 每次充满电对您的电池保养有好处。'
  265. elif finishedState == '01':
  266. desc = u'可能是插头被拔掉,或者电瓶已经充满。系统判断为异常断电,由于电瓶车充电器种类繁多,可能存在误差。如有问题,请您及时联系商家协助解决问题并恢复充电。'
  267. elif finishedState == '02':
  268. desc = u'恭喜您!电池已经充满电!为了用电安全, 已停止供电。'
  269. elif finishedState == '03':
  270. desc = u'电池没有充满!设备或端口出现问题,为了安全起见,被迫停止工作。建议您根据已经充电的时间评估是否需要到现场换到其他端口充电。'
  271. elif finishedState == '04':
  272. desc = u'过载切断输出。'
  273. elif finishedState == '05':
  274. desc = u'警告!您的电池功率超过本机最大限制,已经停止充电,为了公共安全,不建议您在该充电桩充电!提醒您,为了安全,大功率的电池不要放入楼道、室内等位置充电哦。'
  275. return {
  276. 'status': Const.DEV_WORK_STATUS_IDLE,
  277. 'finishedState': finishedState,
  278. 'cmdCode': cmdCode,
  279. 'port': port,
  280. 'leftTime': leftTime,
  281. 'reason': desc
  282. }
  283. elif cmdCode == '0D':
  284. port = int(data[6:8], 16)
  285. errCode = int(data[8:10], 16)
  286. if errCode == '01':
  287. return {'status': Const.DEV_WORK_STATUS_FAULT, 'statusInfo': u'端口输出故障', 'cmdCode': cmdCode,
  288. 'port': port, 'FaultCode': errCode}
  289. elif errCode == '02':
  290. return {'status': Const.DEV_WORK_STATUS_FAULT, 'statusInfo': u'机器整体充电功率过大', 'cmdCode': cmdCode,
  291. 'port': port, 'FaultCode': errCode}
  292. elif errCode == '03':
  293. return {'status': Const.DEV_WORK_STATUS_FAULT, 'statusInfo': u'电源故障', 'cmdCode': cmdCode, 'port': port,
  294. 'FaultCode': errCode}
  295. # 查询当前端口充电状态
  296. def get_port_info(self, line):
  297. # 加1匹配0~9
  298. data = fill_2_hexByte(hex(int(line) + 1), 2)
  299. devInfo = MessageSender.send(self.device, self.make_random_cmdcode(),
  300. {'IMEI': self._device['devNo'], "funCode": '06', 'data': data})
  301. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  302. if devInfo['rst'] == -1:
  303. raise ServiceException(
  304. {'result': 2, 'description': u'充电桩正在玩命找网络,请您稍候再试'})
  305. elif devInfo['rst'] == 1:
  306. raise ServiceException(
  307. {'result': 2, 'description': u'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})
  308. data = devInfo['data'][6::]
  309. leftTime = int(data[2:6], 16)
  310. if data[6:10] == 'FFFF':
  311. power = 0
  312. else:
  313. power = int(data[6:10], 16)
  314. return {'port': line, 'leftTime': leftTime, 'power': power}
  315. # 查询消费总额数据
  316. def get_dev_consume_count(self):
  317. devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
  318. {'IMEI': self._device['devNo'], "funCode": '07', 'data': '00'})
  319. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  320. if devInfo['rst'] == -1:
  321. raise ServiceException(
  322. {'result': 2, 'description': u'充电桩正在玩命找网络,请您稍候再试'})
  323. elif devInfo['rst'] == 1:
  324. raise ServiceException(
  325. {'result': 2, 'description': u'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})
  326. data = devInfo['data'][6::]
  327. cardFee = int(data[0:4], 16)
  328. coinFee = int(data[4:8], 16)
  329. return {'cardFee': cardFee, 'coinFee': coinFee}
  330. # 设置IC卡、投币器是否可用
  331. def set_coin_card_enable(self, infoDict):
  332. data = ''
  333. if infoDict.has_key('putCoins'):
  334. data += '01'
  335. else:
  336. infoDict['putCoins'] = False
  337. data += '00'
  338. if infoDict.has_key('icCard'):
  339. data += '01'
  340. else:
  341. infoDict['icCard'] = False
  342. data += '00'
  343. devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
  344. {'IMEI': self._device['devNo'], "funCode": '09', 'data': data})
  345. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  346. if devInfo['rst'] == -1:
  347. raise ServiceException(
  348. {'result': 2, 'description': u'充电桩正在玩命找网络,请您稍候再试'})
  349. elif devInfo['rst'] == 1:
  350. raise ServiceException(
  351. {'result': 2, 'description': u'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})
  352. try:
  353. conf = Device.objects.get(devNo=self._device['devNo']).otherConf
  354. conf.update({'putCoins': infoDict['putCoins'], 'icCard': infoDict['icCard']})
  355. Device.get_collection().update({'devNo': self._device['devNo']}, {'$set': {'otherConf': conf}})
  356. except Exception, e:
  357. logger.error('update dev=%s coin enable ic enable e=%s' % (self._device['devNo'], e))
  358. # 锁定、解锁某一端口
  359. def lock_unlock_port(self, port, lock=True):
  360. lockStr = '00' if lock else '01'
  361. portStr = fill_2_hexByte(hex(int(port) + 1), 2)
  362. devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
  363. {'IMEI': self._device['devNo'], "funCode": '0A', 'data': portStr + lockStr})
  364. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  365. if devInfo['rst'] == -1:
  366. raise ServiceException(
  367. {'result': 2, 'description': u'充电桩正在玩命找网络,请您稍候再试'})
  368. elif devInfo['rst'] == 1:
  369. raise ServiceException(
  370. {'result': 2, 'description': u'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})
  371. if lock:
  372. Device.update_dev_control_cache(self._device['devNo'],
  373. {str(port): {'status': Const.DEV_WORK_STATUS_FORBIDDEN}})
  374. else:
  375. Device.update_dev_control_cache(self._device['devNo'], {str(port): {'status': Const.DEV_WORK_STATUS_IDLE}})
  376. # 配合stop_charging_port使用
  377. def active_deactive_port(self, port, active):
  378. if active:
  379. raise ServiceException({'result': 2, 'description': u'该设备不支持直接打开端口'})
  380. self.stop_charging_port(port)
  381. devInfo = Device.get_dev_control_cache(self._device['devNo'])
  382. portCtrInfo = devInfo.get(str(port), {})
  383. portCtrInfo.update({'isStart': False, 'status': Const.DEV_WORK_STATUS_IDLE,
  384. 'endTime': datetime.datetime.now().strftime(Const.DATETIME_FMT)})
  385. newValue = {str(port): portCtrInfo}
  386. Device.update_dev_control_cache(self._device['devNo'], newValue)
  387. # 远程停止某个端口的使用
  388. def stop_charging_port(self, port):
  389. portStr = fill_2_hexByte(hex(int(port) + 1), 2)
  390. devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
  391. {'IMEI': self._device['devNo'], "funCode": '0B', 'data': portStr})
  392. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  393. if devInfo['rst'] == -1:
  394. raise ServiceException(
  395. {'result': 2, 'description': u'充电桩正在玩命找网络,请您稍候再试'})
  396. elif devInfo['rst'] == 1:
  397. raise ServiceException(
  398. {'result': 2, 'description': u'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})
  399. data = devInfo['data'][6::]
  400. port = int(data[0:2], 16)
  401. leftTime = int(data[2:6], 16)
  402. return {'port': port, 'leftTime': leftTime}
  403. # 个人中心远程停止端口
  404. def stop(self, port = None):
  405. infoDict = self.stop_charging_port(port)
  406. infoDict['remainder_time'] = infoDict['leftTime']
  407. return infoDict
  408. # 设置设备参数
  409. def set_param_setting(self, infoDict):
  410. data = ''
  411. if infoDict.has_key('autoStop'):
  412. if infoDict['autoStop']:
  413. data += '01'
  414. elif not infoDict['autoStop']:
  415. data += '00'
  416. else:
  417. infoDict['autoStop'] = False
  418. data += '00'
  419. section = ''
  420. if infoDict.has_key('funcParam'):
  421. if infoDict['funcParam'] == 0:
  422. section += '00'
  423. elif infoDict['funcParam'] == 1:
  424. section += '01'
  425. elif infoDict['funcParam'] == 2:
  426. section += '02'
  427. elif infoDict['funcParam'] == 3:
  428. section += '03'
  429. else:
  430. section += '00'
  431. devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
  432. {'IMEI': self._device['devNo'], "funCode": '16', 'data': data + '00' + section})
  433. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  434. if devInfo['rst'] == -1:
  435. raise ServiceException(
  436. {'result': 2, 'description': u'充电桩正在玩命找网络,请您稍候再试'})
  437. elif devInfo['rst'] == 1:
  438. raise ServiceException(
  439. {'result': 2, 'description': u'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})
  440. try:
  441. conf = Device.objects.get(devNo=self._device['devNo']).otherConf
  442. conf.update({'autoStop': infoDict['autoStop'], 'cardRefund': infoDict['cardRefund'],
  443. 'funcParam': infoDict['funcParam']})
  444. Device.get_collection().update({'devNo': self._device['devNo']}, {'$set': {'otherConf': conf}})
  445. except Exception, e:
  446. logger.error('update dev=%s coin enable ic enable e=%s' % (self._device['devNo'], e))
  447. # 获取设备参数
  448. def get_param_setting(self):
  449. try:
  450. dev = Device.objects.get(devNo=self._device['devNo'])
  451. except Exception, e:
  452. logger.error('get dev error = %s' % e)
  453. return {'autoStop': False, 'cardRefund': False, 'funcParam': 0}
  454. return {
  455. 'autoStop': dev['otherConf'].get('autoStop', False),
  456. 'cardRefund': dev['otherConf'].get('cardRefund', False),
  457. 'funcParam': dev['otherConf'].get('funcParam', 0)
  458. }
  459. # 设备重启
  460. def set_device_restart(self):
  461. devInfo = MessageSender.send(self.device, 220, {'IMEI': self._device['devNo'], "funCode": '20', 'data': '00'})
  462. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  463. if devInfo['rst'] == -1:
  464. raise ServiceException(
  465. {'result': 2, 'description': u'充电桩正在玩命找网络,请您稍候再试'})
  466. elif devInfo['rst'] == 1:
  467. raise ServiceException(
  468. {'result': 2, 'description': u'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})
  469. def set_device_function(self, request, lastSetConf):
  470. if request.POST.has_key('putCoins'):
  471. # putCoins = True if request.POST.get('putCoins') == 'true' else False
  472. putCoins = request.POST.get("putCoins", False)
  473. lastSetConf.update({'putCoins': putCoins})
  474. self.set_coin_card_enable(lastSetConf)
  475. if request.POST.has_key('icCard'):
  476. # icCard = True if request.POST.get('icCard') == 'true' else False
  477. icCard = request.POST.get("icCard", False)
  478. lastSetConf.update({'icCard': icCard})
  479. self.set_coin_card_enable(lastSetConf)
  480. if request.POST.has_key('autoStop'):
  481. # autoStop = True if request.POST.get('autoStop') == 'true' else False
  482. autoStop = request.POST.get("autoStop", False)
  483. lastSetConf.update({'autoStop': autoStop})
  484. self.set_param_setting(lastSetConf)
  485. if request.POST.has_key('cardRefund'):
  486. # cardRefund = True if request.POST.get('cardRefund') == 'true' else False
  487. cardRefund = request.POST.get("cardRefund", False)
  488. lastSetConf.update({'cardRefund': cardRefund})
  489. self.set_param_setting(lastSetConf)
  490. if request.POST.has_key('reboot'):
  491. if request.POST.get('reboot'):
  492. self.set_device_restart()
  493. def set_device_function_param(self, request, lastSetConf):
  494. icMoney = request.POST.get('icMoney', None)
  495. icTime = request.POST.get('icTime', None)
  496. tbTime = request.POST.get('tbTime', None)
  497. stdPower = request.POST.get('stdPower', None)
  498. maxPower = request.POST.get('maxPower', None)
  499. autoStop = request.POST.get('autoStop', None)
  500. funcParam = request.POST.get('funcParam', 0)
  501. if icMoney:
  502. lastSetConf.update({'icMoney': int(icMoney)})
  503. if icTime:
  504. lastSetConf.update({'icTime': int(icTime)})
  505. if tbTime:
  506. lastSetConf.update({'tbTime': int(tbTime)})
  507. if stdPower:
  508. lastSetConf.update({'stdPower': int(stdPower)})
  509. if maxPower:
  510. lastSetConf.update({'maxPower': int(maxPower)})
  511. if autoStop is not None:
  512. lastSetConf.update({'autoStop': autoStop})
  513. if funcParam:
  514. lastSetConf.update({'funcParam': int(funcParam)})
  515. self.set_dev_setting(lastSetConf)
  516. self.set_param_setting(lastSetConf)
  517. def get_port_number_from_type_code(self):
  518. try:
  519. devTypeCode = self.device['devType']['code']
  520. if devTypeCode == Const.DEVICE_TYPE_CODE_CHARGING_SIJIANG:
  521. return 10
  522. elif devTypeCode == Const.DEVICE_TYPE_CODE_CHANGING_SIJIANG20:
  523. return 20
  524. elif devTypeCode == Const.DEVICE_TYPE_CODE_CHARGING_SIJIANG4:
  525. return 4
  526. else:
  527. return 10
  528. except Exception as e:
  529. return 10
  530. @property
  531. def isHaveStopEvent(self):
  532. return True