caiyi.py 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735
  1. # coding=utf-8
  2. import logging
  3. import time
  4. from typing import TYPE_CHECKING
  5. from apilib.utils_json import JsonResponse
  6. from apilib.utils_string import cn
  7. from apps import serviceCache
  8. from apps.web.constant import Const, DeviceCmdCode, ErrorCode, MQTT_TIMEOUT
  9. from apps.web.core.adapter.base import SmartBox, hexbyte_2_bin, fill_2_hexByte, SendManager
  10. from apps.web.core.exceptions import ServiceException
  11. from apps.web.device.models import Device
  12. from apps.web.core.exceptions import TestError
  13. logger = logging.getLogger(__name__)
  14. if TYPE_CHECKING:
  15. from apps.web.core.device_define import PackageDict
  16. from apps.web.user.models import ConsumeRecord
  17. class WasherBox(SmartBox):
  18. WASH_NAME_MAP = {
  19. Const.WASHER_BOX_SET_DWX: "01",
  20. Const.WASHER_BOX_SET_BZX: "02",
  21. Const.WASHER_BOX_SET_KSX: "04",
  22. Const.WASHER_BOX_SET_DTS: "08",
  23. Const.WASHER_BOX_SET_TQJ: "10",
  24. }
  25. # 匹配烘干机的需求
  26. HONG_GAN = {
  27. u"加时烘干": "08",
  28. u"快速烘干": "04",
  29. u"标准烘干": "02",
  30. u"特别烘干": "01"
  31. }
  32. HONG_GAN_PROGRAM_MAP = {
  33. "01": "加时烘干",
  34. "02": "快速烘干",
  35. "03": "标准烘干",
  36. "04": "特别烘干",
  37. }
  38. DEVICE_STATUS_MAP = {
  39. "01": (Const.DEV_WORK_STATUS_IDLE, u"待机"),
  40. "02": (Const.DEV_WORK_STATUS_WORKING, u"运转"),
  41. "03": (Const.DEV_WORK_STATUS_PAUSE, u"暂停"),
  42. "04": (Const.DEV_WORK_STATUS_FAULT, u"故障"),
  43. "05": (Const.DEV_WORK_STATUS_WORKING, u"参数设置"),
  44. "06": (Const.DEV_WORK_STATUS_WORKING, u"自检")
  45. }
  46. PROCESS_MAP = {
  47. '01': u'预约',
  48. '02': u'浸泡',
  49. '03': u'洗涤',
  50. '04': u'漂洗',
  51. '05': u'脱水',
  52. '06': u'主进水'
  53. }
  54. PROGRAM_MAP = {
  55. "01": "单脱水",
  56. "02": "快速1",
  57. "03": "快速2",
  58. "04": "标准",
  59. "05": "大物",
  60. }
  61. FAULT_MAP = {
  62. "0100": u"进水超时",
  63. "0200": u"排水超时",
  64. "0400": u"脱水开盖",
  65. "0800": u"脱水不平衡",
  66. "1000": u"通讯故障",
  67. "2000": u"童锁开盖",
  68. "4000": u"溢水",
  69. "8000": u"水位传感器故障",
  70. "0001": u"数据存储故障",
  71. "0002": u"温度传感器故障",
  72. "0004": u"无水加热故障",
  73. "0008": u"电机堵转故障",
  74. "0010": u"IPM温度过高故障",
  75. "0020": u"电机过流故障",
  76. "0040": u"电机缺相故障",
  77. "0080": u"驱动器故障"
  78. }
  79. START_MAP = {
  80. 'dtStart': "08",
  81. 'ksStart': "04",
  82. 'bzStart': "02",
  83. 'dwStart': "01",
  84. "stop": "20",
  85. "pause": "40",
  86. "continue": "80"
  87. }
  88. def __init__(self, *args):
  89. super(WasherBox, self).__init__(*args)
  90. self.devTypeCode = self.device.get("devType", dict()).get("code", Const.DEVICE_TYPE_CODE_WASHER_CY_HS)
  91. def _send_data(self, funCode, data=None, timeout=None, extra=None, visitor="manager"):
  92. timeout = timeout or MQTT_TIMEOUT.NORMAL
  93. data = data or ""
  94. payload = {"funCode": funCode, "data": data}
  95. if extra is None:
  96. extra = dict()
  97. payload.update(extra)
  98. with SendManager(visitor=visitor) as sender:
  99. result = sender.send(
  100. device=self.device,
  101. cmd=DeviceCmdCode.OPERATE_DEV_SYNC,
  102. payload=payload,
  103. timeout=timeout
  104. )
  105. sender.rst = result
  106. # sender.rst = {"rst": 1}
  107. return result
  108. def _get_device_info(self, visitor="manager"):
  109. """
  110. 获取 洗衣机的状态
  111. :return:
  112. """
  113. result = self._send_data("A1", visitor=visitor)
  114. data = result.get("data", "")
  115. status, statusDesc = WasherBox.DEVICE_STATUS_MAP.get(data[6:8], (Const.DEV_WORK_STATUS_IDLE, u"待机"))
  116. if self.device.devTypeCode == "1003053":
  117. program = WasherBox.HONG_GAN_PROGRAM_MAP.get(data[8:10])
  118. process = ""
  119. else:
  120. program = WasherBox.PROGRAM_MAP.get(data[8:10])
  121. process = WasherBox.PROCESS_MAP.get(data[10:12])
  122. leftTime = int(data[14:16] + data[12:14], 16)
  123. if data[16:20] != "0000":
  124. status = Const.DEV_WORK_STATUS_FAULT
  125. statusDesc = WasherBox.FAULT_MAP.get(data[18:20] + data[16:18], u"未知错误")
  126. if status == Const.DEV_WORK_STATUS_FAULT:
  127. statusInfo = statusDesc
  128. elif status == Const.DEV_WORK_STATUS_FORBIDDEN:
  129. statusInfo = u'禁用'
  130. elif status == Const.DEV_WORK_STATUS_IDLE:
  131. statusInfo = u'待机'
  132. elif status == Const.DEV_WORK_STATUS_PAUSE:
  133. statusInfo = u'暂停'
  134. else:
  135. statusInfo = u'%s 当前套餐:%s 当前环节:%s' % (statusDesc, program, process)
  136. return {'status': status, 'statusInfo': statusInfo, 'leftTime': leftTime}
  137. def _check_83_params(self, timeDict):
  138. """
  139. 根据设备类型校验 时间是否会超出主板的最大时间设置
  140. """
  141. timeDt = int(timeDict.get("timeDt", 0))
  142. timeKs = int(timeDict.get("timeKs", 0))
  143. timeBz = int(timeDict.get("timeBz", 0))
  144. timeDw = int(timeDict.get("timeDw", 0))
  145. # 滚筒的
  146. if self.device.devType.get("code", Const.DEVICE_TYPE_CODE_WASHER_CY_HS) == Const.DEVICE_TYPE_CODE_WASHER_CY_HJ:
  147. if timeDt < 5 or timeDt > 15:
  148. raise ServiceException({"result": 2, "description": u"单脱水时间范围为5-15分钟"})
  149. if timeKs < 20 or timeKs > 35:
  150. raise ServiceException({"result": 2, "description": u"快速洗时间范围为20-35分钟"})
  151. if timeBz < 35 or timeBz > 50:
  152. raise ServiceException({"result": 2, "description": u"标准洗时间范围为35-50分钟"})
  153. if timeDw < 50 or timeDw > 65:
  154. raise ServiceException({"result": 2, "description": u"大物洗时间范围为50-65分钟"})
  155. elif self.device.devType.get("code", Const.DEVICE_TYPE_CODE_WASHER_CY_HS) == Const.DEVICE_TYPE_CODE_WASHER_CY_HS:
  156. if timeDt < 5 or timeDt > 9:
  157. raise ServiceException({"result": 2, "description": u"单脱水时间范围为5-9分钟"})
  158. if timeKs < 20 or timeKs > 32:
  159. raise ServiceException({"result": 2, "description": u"快速洗时间范围为20-32分钟"})
  160. if timeBz < 35 or timeBz > 43:
  161. raise ServiceException({"result": 2, "description": u"标准洗时间范围为35-43分钟"})
  162. if timeDw < 45 or timeDw > 53:
  163. raise ServiceException({"result": 2, "description": u"大物洗时间范围为45-53分钟"})
  164. elif self.device.devTypeCode == Const.DEVICE_TYPE_CODE_WASHER_CY_HJ_1:
  165. if timeDt < 5 or timeDt > 15:
  166. raise ServiceException({"result": 2, "description": u"单脱水时间范围为5-15分钟"})
  167. if timeKs < 18 or timeKs > 35:
  168. raise ServiceException({"result": 2, "description": u"快速洗时间范围为18-35分钟"})
  169. if timeBz < 30 or timeBz > 45:
  170. raise ServiceException({"result": 2, "description": u"标准洗时间范围为30-45分钟"})
  171. if timeDw < 40 or timeDw > 55:
  172. raise ServiceException({"result": 2, "description": u"大物洗时间范围为40-55分钟"})
  173. else:
  174. pass
  175. def serial_test(self, payload):
  176. """
  177. 串口测试
  178. testMode = WASH_NAME_MAP.keys()
  179. :param payload:
  180. :return:
  181. """
  182. timeout = 20
  183. testMode = payload.get("testMode")
  184. funcL = WasherBox.START_MAP.get(testMode)
  185. if not testMode or not funcL:
  186. raise TestError({"description": u"不支持的测试模式"})
  187. # 获取 洗衣机主板上的时间设定 测试的时候直接返回前台 方便与洗衣机显示屏上的数字相对应
  188. cacheKey = "testTimeData-{}".format(self.device.devNo)
  189. testTimeData = serviceCache.get(cacheKey)
  190. if not testTimeData:
  191. result = self._send_data("A3", timeout=timeout, visitor="tester")
  192. timeData = result["data"][6:]
  193. timeDt = int(timeData[0:2], 16)
  194. timeKs = int(timeData[2:4], 16)
  195. timeBz = int(timeData[4:6], 16)
  196. timeDw = int(timeData[6:8], 16)
  197. testTimeData = {
  198. "dtStart": timeDt,
  199. "ksStart": timeKs,
  200. "bzStart": timeBz,
  201. "dwStart": timeDw
  202. }
  203. # 缓存设定10分钟
  204. serviceCache.set(cacheKey, testTimeData, 600)
  205. # 然后下发串口数据
  206. result = self._send_data("81", funcL+"00", timeout=timeout, visitor="tester")
  207. modeNameMap = {
  208. "dtStart": u"单脱水",
  209. "ksStart": u"快速洗",
  210. "bzStart": u"标准洗",
  211. "dwStart": u"大物洗",
  212. "stop": u"停止功能",
  213. "continue": u"继续功能",
  214. "pause": u"继续功能"
  215. }
  216. result["description"] = "测试模式:{}".format(modeNameMap.get(testMode))
  217. if testMode in testTimeData.keys():
  218. result["description"] += " 启动时间:{}分钟".format(testTimeData.get(testMode))
  219. return result
  220. def start_device(self, package, openId, attachParas):
  221. washName = package.get("name", "")
  222. # 适配一下烘干
  223. if self.device.devTypeCode == "1003053":
  224. m = WasherBox.HONG_GAN
  225. else:
  226. m = WasherBox.WASH_NAME_MAP
  227. funcLHex = m.get(washName)
  228. funcHHex = "00"
  229. if not funcLHex:
  230. raise ServiceException({'result': 2, 'description': u'无效的套餐'})
  231. if openId:
  232. result = self._send_data(funCode="81", data=funcLHex+funcHHex, visitor="client", timeout = MQTT_TIMEOUT.START_DEVICE)
  233. else:
  234. result = self._send_data(funCode="81", data=funcLHex+funcHHex)
  235. needTime = package.get("time")
  236. devCache = {
  237. "openId": openId,
  238. "washName": washName,
  239. "needTime": needTime,
  240. }
  241. Device.update_dev_control_cache(self.device.devNo, devCache)
  242. result["finishedTime"] = 60 * int(needTime) + int(time.time())
  243. return result
  244. def start_device_realiable(self, order):
  245. # type:(ConsumeRecord)->dict
  246. try:
  247. package = order.my_package # type: PackageDict
  248. funcLHex = WasherBox.WASH_NAME_MAP.get(package.name)
  249. funcHHex = "00"
  250. if not funcLHex:
  251. raise ServiceException({'result': 2, 'description': u'无效的套餐'})
  252. work_time = package.estimated_duraion
  253. result = self._send_data(
  254. funCode="81",
  255. data=funcLHex+funcHHex,
  256. extra={'order_type': 'com_start', 'order_id': order.orderNo, 'time': work_time},
  257. visitor="client",
  258. timeout = MQTT_TIMEOUT.START_DEVICE
  259. )
  260. if result['rst'] == ErrorCode.DEVICE_CONN_FAIL:
  261. result.update({
  262. 'fts': int(time.time()),
  263. 'order_type': 'com_start',
  264. 'order_id': order.orderNo
  265. })
  266. except ServiceException as e:
  267. logger.exception(e)
  268. return {
  269. 'rst': ErrorCode.EXCEPTION,
  270. 'fts': int(time.time()),
  271. 'errorDesc': cn(e.result.get('description')),
  272. 'order_type': 'com_start',
  273. 'order_id': order.orderNo
  274. }
  275. except Exception as e:
  276. logger.exception(e)
  277. return {
  278. 'rst': ErrorCode.EXCEPTION,
  279. 'fts': int(time.time()),
  280. 'order_type': 'com_start',
  281. 'order_id': order.orderNo
  282. }
  283. return result
  284. def check_dev_status(self, attachParas=None):
  285. """
  286. 检查洗衣机的当前状态
  287. :param attachParas:
  288. :return:
  289. """
  290. status = self._get_device_info(visitor="client").get("status")
  291. # 适配烘干机
  292. if self.device.devTypeCode == "1003053":
  293. deviceName = "烘干机"
  294. else:
  295. deviceName = "洗衣机"
  296. info = self._get_device_info()
  297. if info['status'] == Const.DEV_WORK_STATUS_FAULT:
  298. raise ServiceException(
  299. {'result': 2, 'description': u'当前%s故障:%s' % (deviceName,info['statusInfo'])})
  300. if u'待机' not in info['statusInfo']:
  301. raise ServiceException(
  302. {'result': 2, 'description': u'当前%s%s,请稍候使用' % (deviceName,info['statusInfo'])})
  303. if status != Const.DEV_WORK_STATUS_IDLE:
  304. raise ServiceException({"result": 2, "description": u"请稍后使用"})
  305. # 控制面板
  306. def get_dev_info(self):
  307. return self._get_device_info()
  308. def get_device_function_by_key(self, keyName):
  309. if keyName == 'workingStatus':
  310. infoDict = self._get_device_info()
  311. return {"workingStatus": infoDict['statusInfo']}
  312. return None
  313. # 控制面板
  314. def press_down_key(self, keyName):
  315. if keyName in ['stop', 'pause', 'continue']:
  316. return self.stop_pause_continue(keyName)
  317. elif keyName in ['dtStart', 'ksStart', 'bzStart', 'dwStart']:
  318. return self._send_data("81", WasherBox.START_MAP.get(keyName) + "00")
  319. def stop_pause_continue(self, state):
  320. if state == 'stop':
  321. cmd = '20'
  322. elif state == 'pause':
  323. cmd = '40'
  324. elif state == 'continue':
  325. cmd = '80'
  326. else:
  327. raise ServiceException({"result": 2, "description": u"参数错误"})
  328. cmd += '00'
  329. result = self._send_data("81", cmd)
  330. resCode = result['data'][6:8]
  331. if resCode == '0F':
  332. raise ServiceException({'result': 2, 'description': u'主板通讯失败,请试试投币,并报障给老板哦'})
  333. if state == 'stop':
  334. Device.update_dev_control_cache(self._device['devNo'], {'status': Const.DEV_WORK_STATUS_IDLE})
  335. else:
  336. Device.update_dev_control_cache(self._device['devNo'], {'status': Const.DEV_WORK_STATUS_WORKING})
  337. return result
  338. def get_config_A2(self):
  339. # 获取价格设置
  340. result = self._send_data("A2")
  341. priceData = result["data"][6:]
  342. priceDt = int(priceData[0:2], 16)
  343. priceKs = int(priceData[2:4], 16)
  344. priceBz = int(priceData[4:6], 16)
  345. priceDw = int(priceData[6:8], 16)
  346. sourceData = {
  347. "priceDt": priceDt,
  348. "priceKs": priceKs,
  349. "priceBz": priceBz,
  350. "priceDw": priceDw
  351. }
  352. # 保留源数据
  353. otherConf = self.device.get("otherConf", dict())
  354. otherConf.update(sourceData)
  355. Device.objects.filter(devNo = self.device.devNo).update(otherConf = otherConf)
  356. Device.invalid_device_cache(self.device.devNo)
  357. return sourceData
  358. def get_config_A3(self):
  359. result = self._send_data("A3")
  360. timeData = result["data"][6:]
  361. timeDt = int(timeData[0:2], 16)
  362. timeKs = int(timeData[2:4], 16)
  363. timeBz = int(timeData[4:6], 16)
  364. timeDw = int(timeData[6:8], 16)
  365. sourceData = {
  366. "timeDt": timeDt,
  367. "timeKs": timeKs,
  368. "timeBz": timeBz,
  369. "timeDw": timeDw
  370. }
  371. otherConf = self.device.get("otherConf", dict())
  372. otherConf.update(sourceData)
  373. Device.objects.filter(devNo = self.device.devNo).update(otherConf = otherConf)
  374. Device.invalid_device_cache(self.device.devNo)
  375. return sourceData
  376. def get_config_A4(self):
  377. result = self._send_data("A4")
  378. temp = result['data'][6:16]
  379. paramKs = int(temp[0:2], 16)
  380. paramBz = int(temp[2:4], 16)
  381. paramDw = int(temp[4:6], 16)
  382. sourceData = {
  383. "paramKs": paramKs,
  384. "paramBz": paramBz,
  385. "paramDw": paramDw
  386. }
  387. otherConf = self.device.get("otherConf", dict())
  388. otherConf.update(sourceData)
  389. Device.objects.filter(devNo = self.device.devNo).update(otherConf = otherConf)
  390. Device.invalid_device_cache(self.device.devNo)
  391. return sourceData
  392. def get_config_A5(self):
  393. result = self._send_data("A5")
  394. dataLHex = result['data'][6:8]
  395. dataLBin = hexbyte_2_bin(dataLHex)[::-1]
  396. return {
  397. "ddjy": bool(int(dataLBin[0])),
  398. "qcbcbh": bool(int(dataLBin[1])),
  399. "tqjgn": bool(int(dataLBin[3])),
  400. "aj": bool(int(dataLBin[4])),
  401. "tb": bool(int(dataLBin[5]))
  402. }
  403. def get_config_12(self):
  404. """
  405. 自定义指令 一次性将A2-A5参数设置的数据全部取出
  406. :return:
  407. """
  408. result = self._send_data("12")
  409. data = result.get("data", "")
  410. if data[6:8] != "00":
  411. raise ServiceException({"result": 2, "description": u"获取参数配置失败"})
  412. priceData = data[8:24]
  413. timeData = data[24:40]
  414. waterData = data[40:56]
  415. switchData = data[56:60]
  416. sourceData = dict()
  417. priceDt = int(priceData[0:2], 16)
  418. priceKs = int(priceData[2:4], 16)
  419. priceBz = int(priceData[4:6], 16)
  420. priceDw = int(priceData[6:8], 16)
  421. sourceData.update({
  422. "priceDt": priceDt,
  423. "priceKs": priceKs,
  424. "priceBz": priceBz,
  425. "priceDw": priceDw
  426. })
  427. timeDt = int(timeData[0:2], 16)
  428. timeKs = int(timeData[2:4], 16)
  429. timeBz = int(timeData[4:6], 16)
  430. timeDw = int(timeData[6:8], 16)
  431. sourceData.update({
  432. "timeDt": timeDt,
  433. "timeKs": timeKs,
  434. "timeBz": timeBz,
  435. "timeDw": timeDw
  436. })
  437. paramKs = int(waterData[0:2], 16)
  438. paramBz = int(waterData[2:4], 16)
  439. paramDw = int(waterData[4:6], 16)
  440. sourceData.update({
  441. "paramKs": paramKs,
  442. "paramBz": paramBz,
  443. "paramDw": paramDw
  444. })
  445. dataLBin = hexbyte_2_bin(switchData[:2])[::-1]
  446. sourceData.update({
  447. "ddjy": bool(int(dataLBin[0])),
  448. "qcbcbh": bool(int(dataLBin[1])),
  449. "tqjgn": bool(int(dataLBin[3])),
  450. "aj": bool(int(dataLBin[4])),
  451. "tb": bool(int(dataLBin[5]))
  452. })
  453. otherConf = self.device.get("otherConf", dict())
  454. otherConf.update(sourceData)
  455. Device.objects.filter(devNo = self.device.devNo).update(otherConf = otherConf)
  456. Device.invalid_device_cache(self.device.devNo)
  457. return sourceData
  458. def set_config_82(self, data):
  459. priceDt = data.get("priceDt")
  460. priceKs = data.get("priceKs")
  461. priceBz = data.get("priceBz")
  462. priceDw = data.get("priceDw")
  463. if int(priceKs) > 15 or int(priceBz) > 15 or int(priceDt) > 15 or int(priceDw) > 15:
  464. raise ServiceException({"result": 2, "description": u"模式单价不能超过15元"})
  465. sendData = ""
  466. sendData += fill_2_hexByte(hex(int(priceDt)), 2)
  467. sendData += fill_2_hexByte(hex(int(priceKs)), 2)
  468. sendData += fill_2_hexByte(hex(int(priceBz)), 2)
  469. sendData += fill_2_hexByte(hex(int(priceDw)), 2)
  470. sendData += "00000000"
  471. result = self._send_data("82", sendData)
  472. if result.get("data")[6:8] != "F0":
  473. raise ServiceException({"result": 2, "description": "主板设置参数失败"})
  474. def set_config_83(self, data):
  475. self._check_83_params(data)
  476. timeDt = int(data.get("timeDt", 0))
  477. timeKs = int(data.get("timeKs", 0))
  478. timeBz = int(data.get("timeBz", 0))
  479. timeDw = int(data.get("timeDw", 0))
  480. sendData = ""
  481. sendData += fill_2_hexByte(hex(int(timeDt)), 2)
  482. sendData += fill_2_hexByte(hex(int(timeKs)), 2)
  483. sendData += fill_2_hexByte(hex(int(timeBz)), 2)
  484. sendData += fill_2_hexByte(hex(int(timeDw)), 2)
  485. sendData += "00000000"
  486. result = self._send_data("83", sendData)
  487. if result.get("data")[6:8] != "F0":
  488. raise ServiceException({"result": 2, "description": "主板设置参数失败"})
  489. def set_config_84(self, data):
  490. paramKs = data.get("paramKs")
  491. paramBz = data.get("paramBz")
  492. paramDw = data.get("paramDw")
  493. sendData = ""
  494. sendData += fill_2_hexByte(hex(int(paramKs)), 2)
  495. sendData += fill_2_hexByte(hex(int(paramBz)), 2)
  496. sendData += fill_2_hexByte(hex(int(paramDw)), 2)
  497. sendData += "0000000000"
  498. result = self._send_data("84", sendData)
  499. if result.get("data")[6:8] != "F0":
  500. raise ServiceException({"result": 2, "description": "主板设置参数失败"})
  501. def set_config_85(self, data):
  502. ddjy = data.get("ddjy")
  503. qcbcbh = data.get("qcbcbh")
  504. tqjgn = data.get("tqjgn")
  505. aj = data.get("aj")
  506. tb = data.get("tb")
  507. sendData = "00"
  508. sendData += str(int(tb))
  509. sendData += str(int(aj))
  510. sendData += str(int(tqjgn))
  511. sendData += "0"
  512. sendData += str(int(qcbcbh))
  513. sendData += str(int(ddjy))
  514. sendData = fill_2_hexByte(hex(int(sendData, 2)), 2)
  515. result = self._send_data("85", sendData + "00")
  516. if result.get("data")[6:8] != "F0":
  517. raise ServiceException({"result": 2, "description": "主板设置参数失败"})
  518. def get_dev_setting(self):
  519. driverVersion = Device.get_dev(self.device.devNo).get("driverVersion", "v1.0.0").rsplit(".", 1)[1]
  520. if int(driverVersion) < 3 and self.device.driverVersion.startswith("v1"):
  521. confA2 = self.get_config_A2()
  522. confA3 = self.get_config_A3()
  523. confA4 = self.get_config_A4()
  524. confA5 = self.get_config_A5()
  525. data = dict(confA2.items() + confA3.items() + confA4.items() + confA5.items())
  526. # data = dict(confA2.items() + confA3.items() + confA4.items())
  527. else:
  528. data = self.get_config_12()
  529. #服务器参数
  530. if self.device['otherConf'] and self.device['otherConf'].get('cardPrice') and self.device['otherConf'].get('eachCoin'):
  531. data['cardPrice'] = self.device['otherConf']['cardPrice']
  532. data['eachCoin'] = self.device['otherConf']['eachCoin']
  533. Device.invalid_device_cache(self.device.devNo)
  534. return data
  535. def set_device_function(self, request, lastSetConf):
  536. if self._get_device_info().get("status") != Const.DEV_WORK_STATUS_IDLE:
  537. raise ServiceException({"result": 2, "description": "请先停止使用设备,使设备处于待机状态"})
  538. data = self.get_config_A5()
  539. sendData = {k: v if request.POST.get(k) is None else request.POST.get(k) for k, v in data.items()}
  540. return self.set_config_85(sendData)
  541. def set_device_function_param(self, request, lastSetConf):
  542. if self._get_device_info().get("status") != Const.DEV_WORK_STATUS_IDLE:
  543. raise ServiceException({"result": 2, "description": "请先停止使用设备,使设备处于待机状态"})
  544. priceSettings = request.POST.get("priceBz")
  545. timeSettings = request.POST.get("timeBz")
  546. paramSettings = request.POST.get("paramBz")
  547. cardPrice = request.POST.get("cardPrice")
  548. eachCoin = request.POST.get("eachCoin")
  549. #服务器参数
  550. if cardPrice and eachCoin:
  551. if not str(cardPrice).isdigit():
  552. raise ServiceException({"result": 2, "description": "刷卡单价必须为整数"})
  553. if not str(eachCoin).isdigit():
  554. raise ServiceException({"result": 2, "description": "脉冲次数必须为整数"})
  555. cardPrice = int(cardPrice)
  556. packages = self.device['washConfig']
  557. packages = sorted(packages.values(), key=lambda x: x["coins"])
  558. min_coin = int(packages[0].get("coins"))
  559. max_coin = int(packages[-1].get("coins"))
  560. eachCoin = int(eachCoin)
  561. if min_coin > eachCoin or max_coin<eachCoin:
  562. raise ServiceException({"result": 2, "description": "脉冲次数不能超过套餐投币数范围"})
  563. dic = {
  564. 'cardPrice':cardPrice,
  565. 'eachCoin':eachCoin
  566. }
  567. dev = Device.objects.get(devNo=self.device.devNo)
  568. dev.otherConf.update(dic)
  569. dev.save()
  570. dev.invalid_device_cache(dev.devNo)
  571. if priceSettings is not None:
  572. self.set_config_82(request.POST)
  573. if timeSettings is not None:
  574. self.set_config_83(request.POST)
  575. if paramSettings is not None:
  576. self.set_config_84(request.POST)
  577. def count_down(self, request, dev, agent, group, devType, lastOpenId, port = None):
  578. devInfo = self._get_device_info()
  579. if devInfo['rst'] == -1:
  580. return JsonResponse({'result': 0, 'description': u'洗衣机网络不太好,您试下投币,或者周边其他设备,或者稍后再试试哦'})
  581. if devInfo['rst'] == 1:
  582. return JsonResponse({'result': 0, 'description': u'洗衣机设备主板连接故障,请投币试试'})
  583. if devInfo['status'] == Const.WASHER_BOX_GZ:
  584. statusDesc = Const.WASHER_STATUS_CODE_DESC[Const.WASHER_BOX_GZ]
  585. if len(devInfo['faultList']) > 0:
  586. faultDesc = Const.EVENT_CODE_DESC[devInfo['faultList'][0]]
  587. desc = '出现了%s,%s' % (statusDesc, faultDesc)
  588. else:
  589. desc = '出现了%s' % statusDesc
  590. return JsonResponse({'result': 0, 'description': u'洗衣机' + desc + u'。您联系下老板哦'})
  591. return JsonResponse(
  592. {
  593. 'result': 1,
  594. 'description': '',
  595. 'payload': {
  596. 'surplus': devInfo['surplus'],
  597. 'sum': devInfo['surplus'],
  598. 'name': group['groupName'],
  599. 'address': group['address'],
  600. 'code': devType.get('code'),
  601. 'orderProcessing': False,
  602. 'logicalCode': dev['logicalCode'],
  603. 'user': 'me' if lastOpenId == request.user.openId else 'notme',
  604. 'agentFeatures': agent.features,
  605. }
  606. })