zhenguduo.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. # -*- coding: utf-8 -*-
  2. # !/usr/bin/env python
  3. import datetime
  4. import time
  5. from apps.web.constant import DeviceCmdCode, MQTT_TIMEOUT
  6. from apps.web.core.adapter.base import SmartBox, asc_to_string, reverse_hex, hexbyte_2_bin, fill_2_hexByte
  7. from apps.web.core.exceptions import ServiceException
  8. from apps.web.core.networking import MessageSender
  9. from apps.web.device.models import Device, Group
  10. from apps.web.user.models import MyUser
  11. from taskmanager.mediator import task_caller
  12. class FunCode(object):
  13. GET_DEV_ATTR = "12"
  14. GET_DEV_STATUS = "13"
  15. GET_PARAS = "15"
  16. SET_PARAS = "16"
  17. LOCK_DEVICE = "17"
  18. SET_LEFT_CUP = "18"
  19. CHARGE_MONEY = "19"
  20. RECOVERY = "1A"
  21. SET_CONCENTRATION = "1B"
  22. REMOTE_CUP = "21"
  23. REBOOT = "22"
  24. class ZhenguduoBox(SmartBox):
  25. DEV_MOD = {
  26. 0: u"Boot模式",
  27. 1: u"App模式"
  28. }
  29. DRINK_MOD = {
  30. 0 : u"禁止",
  31. 1 : u"定量热饮",
  32. 2 : u"定量冷饮",
  33. # 3 : u"定量冷饮+定量热饮",
  34. # 4 : u"定量热水",
  35. # 5 : u"定量冷水",
  36. # 6 : u"定量热水+定量冷水",
  37. # 7 : u"连续热饮",
  38. # 8 : u"连续冷饮",
  39. # 9 : u"连续冷饮+连续热饮",
  40. # 10: u"连续热水",
  41. # 11: u"连续冷水",
  42. # 12: u"连续热水+连续冷水"
  43. }
  44. CUP_MOD = {
  45. 0: u"全关",
  46. # 1: u"杯检测打开",
  47. 2: u"落杯+杯检测",
  48. # 3: u"落盖+杯检测",
  49. 4: u"落杯+落盖+杯检测"
  50. }
  51. def _send_data(self, funcCode, sendData=None, cmd=None, timeout=MQTT_TIMEOUT.NORMAL):
  52. """
  53. 发送 报文
  54. :param funcCode: 串口命令
  55. :param sendData: 发送数据
  56. :param cmd: 报文命令
  57. :param timeout: 超时时间
  58. :return:
  59. """
  60. if sendData is None:
  61. sendData = ""
  62. if cmd is None:
  63. cmd = DeviceCmdCode.OPERATE_DEV_SYNC
  64. if timeout is None:
  65. timeout = MQTT_TIMEOUT.NORMAL
  66. result = MessageSender.send(device = self.device, cmd = cmd, payload = {
  67. "IMEI": self._device["devNo"],
  68. "funCode": funcCode,
  69. "data": sendData
  70. }, timeout = timeout)
  71. if "rst" in result:
  72. if result["rst"] == -1:
  73. raise ServiceException({'result': 2, 'description': u'饮料机正在玩命找网络,请稍候再试'})
  74. elif result["rst"] == 1:
  75. raise ServiceException({'result': 2, 'description': u'饮料机主板连接故障'})
  76. elif result["rst"] == 0:
  77. return result
  78. else:
  79. raise ServiceException({'result': 2, 'description': u'系统错误'})
  80. else:
  81. raise ServiceException({'result': 2, 'description': u'系统错误'})
  82. def get_dev_attr(self):
  83. """
  84. 获取设备属性
  85. :return:
  86. """
  87. result = self._send_data(funcCode=FunCode.GET_DEV_ATTR)
  88. data = result.get("data")
  89. devMode = self.DEV_MOD.get(int(data[8:10], 16), u"Boot模式")
  90. buttonNum = int(data[10: 12], 16)
  91. portNum = int(data[12: 14], 16)
  92. serialNo = data[14: 30]
  93. typeNo = asc_to_string(data[30: 66])
  94. version = asc_to_string(data[66: 82])
  95. return {
  96. "devMode": devMode,
  97. "buttonNum": buttonNum,
  98. "portNum": portNum if portNum <= 5 else 5,
  99. "serialNo": serialNo,
  100. "typeNo": typeNo,
  101. "version": version
  102. }
  103. def get_dev_status(self):
  104. """
  105. 查询设备状态值
  106. :return:
  107. """
  108. result = self._send_data(funcCode=FunCode.GET_DEV_STATUS)
  109. data = result.get("data")
  110. portNum = (len(data) - 28) / 8
  111. leftCupNum = int(reverse_hex(data[8: 16]), 16) if data[8: 16] != "FFFFFFFF" else -1
  112. portCupNumList = list()
  113. portCupStatusList = list()
  114. for port in xrange(portNum):
  115. tempHex = reverse_hex(data[16+port*8: 24+port*8])
  116. portCupNumList.append(int(tempHex, 16))
  117. portBytesNum = portNum * 4 * 2
  118. status0 = hexbyte_2_bin(data[(16 + portBytesNum):(16 + portBytesNum + 2)])
  119. status1 = hexbyte_2_bin(data[(16 + portBytesNum + 2):(16 + portBytesNum + 4)])
  120. status2 = hexbyte_2_bin(data[(16 + portBytesNum + 4):(16 + portBytesNum + 6)])
  121. # 做饮料标志位 1 bin 代表一个口子,最多支持32个口子
  122. for ii in hexbyte_2_bin(data[(24+portBytesNum):(26+portBytesNum)]):
  123. portCupStatusList.append(ii)
  124. for ii in hexbyte_2_bin(data[(26+portBytesNum):(28+portBytesNum)]):
  125. portCupStatusList.append(ii)
  126. for ii in hexbyte_2_bin(data[(28+portBytesNum):(30+portBytesNum)]):
  127. portCupStatusList.append(ii)
  128. for ii in hexbyte_2_bin(data[(30+portBytesNum):(32+portBytesNum)]):
  129. portCupStatusList.append(ii)
  130. return {
  131. 'leftCupNum': leftCupNum, # 设备剩余做杯数
  132. 'portCupNumList': portCupNumList, # 各口子累积杯数
  133. 'isReady': int(status0[0]), # 上电后完成上电抽水和上电加热的待机标志
  134. 'isLackWater': int(status0[1]), # 抽水/缺水标志
  135. 'isHotting': int(status0[2]), # 加热标志
  136. 'isConnectFault': int(status0[3]), # 按键板和驱动板通信故障标志
  137. 'isHottingTimeout': int(status0[4]), # 加热超时标志
  138. 'isColdingTimeout': int(status0[5]), # 制冷超时标志
  139. 'isHotWaterSensorFault': int(status0[6]), # 热水温度传感器故障标志
  140. 'isColdWaterSensorFault': int(status0[7]), # 冷水温度传感器故障标志
  141. 'isLock': int(status1[0]), # 童锁标志
  142. 'isLackOfCup': int(status1[1]), # 缺杯标志
  143. 'isLackOfCap': int(status1[2]), # 缺盖标志
  144. 'isLackOfPowder': int(status1[3]), # 缺粉标志
  145. 'isLackOfSyrup': int(status1[4]), # 缺浆标志
  146. 'isPowderMachineFault': int(status1[5]), # 出粉电机故障标志
  147. 'isWaterMachineFault': int(status1[6]), # 抽水超时/抽水电机故障标志
  148. 'isMixMachineFault': int(status1[7]), # 搅拌电机故障标志
  149. 'isHotWaterValveFault': int(status2[0]), # 冷水电磁阀故障标志
  150. 'isColdWaterValveFault': int(status2[1]), # 热水电磁阀故障标志
  151. 'isDeviceLock': int(status2[2]), # 设备强制锁定标志
  152. # 'portCupStatusList': portCupStatusList # 做饮料标志
  153. }
  154. def get_port_paras(self, port):
  155. """
  156. 获取端口设置
  157. :param port: 端口号
  158. :return:
  159. """
  160. portHex = fill_2_hexByte(hex(int(port)), 2)
  161. result = self._send_data(funcCode=FunCode.GET_PARAS, sendData=portHex)
  162. data = result.get("data")
  163. portNum = int(reverse_hex(data[8: 10]), 16)
  164. makeDrinkMode = int(reverse_hex(data[10: 12]), 16)
  165. hotWater = int(reverse_hex(data[12: 16]), 16)
  166. coldWater = int(reverse_hex(data[16: 20]), 16)
  167. hotPowder = int(reverse_hex(data[20: 24]), 16)
  168. coldPowder = int(reverse_hex(data[24: 28]), 16)
  169. # 更新缓存中的饮料模式
  170. Device.update_dev_control_cache(self._device["devNo"], {str(portNum+1): {"makeDrinkMode": makeDrinkMode}})
  171. return {
  172. "portNum": portNum,
  173. "makeDrinkMode": str(makeDrinkMode),
  174. "hotWater": hotWater,
  175. "coldWater": coldWater,
  176. "hotPowder": hotPowder,
  177. "coldPowder": coldPowder
  178. }
  179. def get_dev_paras(self):
  180. """
  181. 获取设备参数, 命令字与获取端口参数一样,传递的端口号为 FF
  182. :return:
  183. """
  184. result = self._send_data(funcCode=FunCode.GET_PARAS, sendData="FF")
  185. data = result.get("data")[8: ]
  186. hotSwitch = int(reverse_hex(data[2:4]), 16)
  187. hotWaterMax = int(reverse_hex(data[4:8]), 16)
  188. hotWaterMin = int(reverse_hex(data[8:12]), 16)
  189. coldSwitch = int(reverse_hex(data[12:14]), 16)
  190. coldWaterMax = int(reverse_hex(data[14:18]), 16)
  191. coldWaterMin = int(reverse_hex(data[18:22]), 16)
  192. # 第二版协议修改 童锁时间改为2个字节 去掉锁定开关 杯检测和落杯合并为杯模式
  193. lockTime = int(reverse_hex(data[22:26]), 16)
  194. payModuleSwitch = int(reverse_hex(data[26:28]), 16)
  195. cupModule = int(reverse_hex(data[28:30]), 16)
  196. lightSwitch = int(reverse_hex(data[30:32]), 16)
  197. leftCupSwitch = int(reverse_hex(data[32:34]), 16)
  198. return {
  199. 'hotSwitch': hotSwitch, # 加热开关
  200. 'hotWaterMax': hotWaterMax, # 热水温上限
  201. 'hotWaterMin': hotWaterMin, # 热水温下限
  202. 'coldSwitch': coldSwitch, # 制冷开关
  203. 'coldWaterMax': coldWaterMax, # 冷水温上限
  204. 'coldWaterMin': coldWaterMin, # 冷水温下限
  205. 'lockTime': lockTime, # 童锁时间
  206. 'payModuleSwitch': payModuleSwitch, # 支付模块开关
  207. 'cupModule': cupModule, # 杯模式
  208. 'lightSwitch': lightSwitch, # 灯带开关
  209. 'leftCupSwitch': leftCupSwitch # 剩余杯数开关 (不支持)
  210. }
  211. def set_port_paras(self, port, setConf):
  212. """
  213. 设置设备参数
  214. :param port: 端口号
  215. :param setConf: 设置参数
  216. :return:
  217. """
  218. # 注意:99.9秒(999)>=热水水量>=热水粉量+2秒(20),
  219. # 999秒(999)>=冷水水量>=冷水粉量+2秒(20)
  220. # 95度>=热水温上限>=热水温下限+5度>=5度,
  221. # 20度>=冷水温上限>=冷水温下限+5度>=3度,
  222. # 童锁时间<=999秒
  223. hotWater = int(setConf.get("hotWater", 0))
  224. coldWater = int(setConf.get("coldWater", 0))
  225. hotPowder = int(setConf.get("hotPowder", 0))
  226. coldPowder = int(setConf.get("coldPowder", 0))
  227. makeDrinkMode = int(setConf.get("makeDrinkMode"))
  228. # 热饮检测
  229. if makeDrinkMode == 1 and not (999 >= hotWater >= hotPowder + 20):
  230. raise ServiceException({'result': 2, 'description': u'热水水量以及热粉必须满足如下条件:99.9>=热水水量>=热粉分量+20'})
  231. # 冷饮检测
  232. if makeDrinkMode == 2 and not (999 >= coldWater >= coldPowder + 20):
  233. raise ServiceException({'result': 2, 'description': u'冷水水量以及冷粉必须满足如下条件:99.9>=冷水水量>=冷粉分量+20'})
  234. portHex = fill_2_hexByte(hex(int(port)), 2)
  235. dataHex = portHex
  236. dataHex += fill_2_hexByte(hex(int(setConf.get("makeDrinkMode"))), 2, reverse=True)
  237. dataHex += fill_2_hexByte(hex(int(setConf.get("hotWater"))), 4, reverse=True)
  238. dataHex += fill_2_hexByte(hex(int(setConf.get("coldWater"))), 4, reverse=True)
  239. dataHex += fill_2_hexByte(hex(int(setConf.get("hotPowder"))), 4, reverse=True)
  240. dataHex += fill_2_hexByte(hex(int(setConf.get("coldPowder"))), 4, reverse=True)
  241. result = self._send_data(funcCode=FunCode.SET_PARAS, sendData=dataHex)
  242. data = result.get("data")
  243. if data[8: 10] != "01":
  244. raise ServiceException({"result": 2, "description": u"参数设置失败"})
  245. # 更新缓存中的饮料模式
  246. Device.update_dev_control_cache(self._device["devNo"], {str(port+1): {"makeDrinkMode": int(setConf.get("makeDrinkMode"))}})
  247. def set_dev_paras(self, setConf):
  248. """
  249. 设置设备参数, 命令字与设置设备端口参数一致, 端口号传递 FF
  250. :param setConf: 设置参数
  251. :return:
  252. """
  253. if setConf.has_key('hotWaterMax') and not (95 >= int(setConf['hotWaterMax']) >= int(setConf['hotWaterMin']) + 5 >= 5):
  254. raise ServiceException({'result': 2, 'description': u'热水水温必须满足如下条件:95度>=热水温上限>=热水温下限+5度>=5度'})
  255. if setConf.has_key('coldWaterMax') and not (20 >= int(setConf['coldWaterMax']) >= int(setConf['coldWaterMin']) + 5 >= 3):
  256. raise ServiceException({'result': 2, 'description': u'冷水水温必须满足如下条件:20度>=冷水温上限>=冷水温下限+5度>=3度'})
  257. if setConf.has_key('lockTime') and not (int(setConf['lockTime']) <= 999):
  258. raise ServiceException({'result': 2, 'description': u'童锁时间必须满足如下条件:童锁时间<=999秒'})
  259. cupModule = setConf["cupModule"]
  260. if int(cupModule) not in self.CUP_MOD.keys():
  261. raise ServiceException({'result': 2, 'description': u'无法修改此类杯模式'})
  262. dataHex = 'FF'
  263. dataHex += fill_2_hexByte(hex(int(setConf['hotSwitch'])), 2, reverse=True)
  264. dataHex += fill_2_hexByte(hex(int(setConf['hotWaterMax'])), 4, reverse=True)
  265. dataHex += fill_2_hexByte(hex(int(setConf['hotWaterMin'])), 4, reverse=True)
  266. dataHex += fill_2_hexByte(hex(int(setConf['coldSwitch'])), 2, reverse=True)
  267. dataHex += fill_2_hexByte(hex(int(setConf['coldWaterMax'])), 4, reverse=True)
  268. dataHex += fill_2_hexByte(hex(int(setConf['coldWaterMin'])), 4, reverse=True)
  269. dataHex += fill_2_hexByte(hex(int(setConf['lockTime'])), 4, reverse=True)
  270. dataHex += fill_2_hexByte(hex(int(setConf['payModuleSwitch'])), 2, reverse=True)
  271. dataHex += fill_2_hexByte(hex(int(setConf['cupModule'])), 2, reverse=True)
  272. dataHex += fill_2_hexByte(hex(int(setConf['lightSwitch'])), 2, reverse=True)
  273. dataHex += fill_2_hexByte(hex(int(setConf['leftCupSwitch'])), 2, reverse=True)
  274. dataHex += "0000000000000000000000"
  275. result = self._send_data(funcCode=FunCode.SET_PARAS, sendData=dataHex)
  276. data = result.get("data")
  277. if data[8: 10] != "01":
  278. raise ServiceException({"result": 2, "description": u"参数设置失败"})
  279. def lock_dev(self, lock, lockType=None):
  280. """
  281. 锁定解锁设备
  282. :param lock: 锁定/解锁 0为解锁 1为上锁
  283. :param lockType: 锁定方式 童锁/远程锁
  284. :return:
  285. """
  286. if lockType is None:
  287. lockType = 0
  288. lockTypeHex = fill_2_hexByte(hex(int(lockType)), 2)
  289. lockHex = fill_2_hexByte(hex(int(lock)), 2)
  290. result = self._send_data(funcCode=FunCode.LOCK_DEVICE, sendData=lockTypeHex+lockHex)
  291. data = result.get("data")
  292. if data[8: 10] != "01":
  293. raise ServiceException({"result": 2, "description": u"设置失败"})
  294. # def set_left_cup(self, leftCupSwitch, leftCupNum):
  295. # """
  296. # 设置剩余杯数开关以及数量
  297. # :param leftCupSwitch:
  298. # :param leftCupNum:
  299. # :return:
  300. # """
  301. # if not leftCupSwitch:
  302. # leftCupNumHex = "00000000"
  303. # else:
  304. # leftCupNumHex = fill_2_hexByte(hex(int(leftCupNum)), 8, reverse=True)
  305. #
  306. # leftCupSwitchHex = fill_2_hexByte(hex(int(leftCupSwitch)), 2, reverse=True)
  307. # result = self._send_data(funcCode=FunCode.SET_LEFT_CUP, sendData=leftCupSwitchHex+leftCupNumHex)
  308. # data = result.get("data")
  309. #
  310. # if data[8: 10] != "01":
  311. # raise ServiceException({"result": 2, "description": u"设置失败"})
  312. # def charge(self, chargeMoney):
  313. # """
  314. # 充值/撤销充值
  315. # :param chargeMoney: 金额为正数是充值, 金额为负数是撤销充值
  316. # :return:
  317. # """
  318. # chargeHex = fill_2_hexByte(hex(int(chargeMoney)), 8)
  319. # result = self._send_data(funcCode=FunCode.CHARGE_MONEY, sendData=chargeHex)
  320. # data = result.get("data")
  321. #
  322. # if data[8: 10] != "01":
  323. # raise ServiceException({"result": 2, "description": u"充值失败"})
  324. def recovery(self, mode=None):
  325. """
  326. 恢复出厂设置
  327. :param mode: 低级模式 高级模式
  328. :return:
  329. """
  330. if mode is None:
  331. mode = 0
  332. modeHex = fill_2_hexByte(hex(int(mode)), 2, reverse=True)
  333. result = self._send_data(funcCode=FunCode.RECOVERY, sendData=modeHex)
  334. data = result.get("data")
  335. if data[8: 10] != "01":
  336. raise ServiceException({"result": 2, "description": u"恢复出场设置失败"})
  337. # def set_concentration(self, keyNo, value):
  338. # """
  339. # 设置 杯的浓度
  340. # :param keyNo: 按键序号
  341. # :param value: 浓度
  342. # :return:
  343. # """
  344. # keyHex = fill_2_hexByte(hex(int(keyNo)), 2, reverse=True)
  345. # valueHex = fill_2_hexByte(hex(int(value)), 2, reverse=True)
  346. # result = self._send_data(funcCode=FunCode.SET_CONCENTRATION, sendData=keyHex+valueHex)
  347. # data = result.get("data")
  348. #
  349. # if data[8: 10] != "01":
  350. # raise ServiceException({"result": 2, "description": u"杯浓度设置失败"})
  351. def remote_cup(self, keyNo):
  352. """
  353. 远程做杯
  354. :param keyNo: 案件序号
  355. :return:
  356. """
  357. keyHex = fill_2_hexByte(hex(int(keyNo)), 2, reverse=True)
  358. result = self._send_data(funcCode=FunCode.REMOTE_CUP, sendData=keyHex)
  359. data = result.get("data")
  360. if data[8: 10] != "01":
  361. raise ServiceException({"result": 2, "description": u"做杯失败,请联系经销商!"})
  362. return result
  363. def reboot(self, mode=None):
  364. """
  365. 重启设备
  366. :param mode: 普通重启/boot重启/app重启
  367. :return:
  368. """
  369. if mode is None:
  370. mode = "0"
  371. modeHex = fill_2_hexByte(hex(int(mode)), 2, reverse=True)
  372. result = self._send_data(funcCode=FunCode.REBOOT, sendData=modeHex)
  373. data = result.get("data")
  374. if data[8: 10] != "01":
  375. raise ServiceException({"result": 2, "description": u"重启设备失败"})
  376. def get_dev_setting(self):
  377. """
  378. 获取设备属性 对接view接口
  379. :return:
  380. """
  381. setConf = dict()
  382. devAttr = self.get_dev_attr()
  383. devStatus = self.get_dev_status()
  384. setConf.update(devAttr)
  385. setConf.update(devStatus)
  386. return setConf
  387. def get_device_function_by_key(self, keyName):
  388. """
  389. 获取设备参数 对接view接口
  390. :param keyName: 空情况 设置设备 否则设置端口
  391. :return:
  392. """
  393. if isinstance(keyName, list):
  394. return self.get_dev_paras()
  395. return self.get_port_paras(keyName)
  396. def set_device_function_param(self, request, lastSetConf):
  397. """
  398. 设置设备参数
  399. :param request:
  400. :param lastSetConf:
  401. :return:
  402. """
  403. # leftCupSwitch = request.POST.get("leftCupSwitch", None)
  404. # leftCupNum = request.POST.get("leftCupNum", None)
  405. # if leftCupSwitch is not None:
  406. # self.set_left_cup(leftCupSwitch, leftCupNum)
  407. lock = request.POST.get("lock", None)
  408. if lock is not None:
  409. print lock
  410. self.lock_dev(lock)
  411. port = request.POST.get("portIndex", None)
  412. if port is not None:
  413. setConf = dict()
  414. setConf["makeDrinkMode"] = request.POST.get("makeDrinkMode")
  415. setConf["hotWater"] = request.POST.get("hotWater")
  416. setConf["coldWater"] = request.POST.get("coldWater")
  417. setConf["hotPowder"] = request.POST.get("hotPowder")
  418. setConf["coldPowder"] = request.POST.get("coldPowder")
  419. return self.set_port_paras(port, setConf)
  420. cupModule = request.POST.get("cupModule", None)
  421. if cupModule is not None:
  422. setConf = dict()
  423. setConf["hotSwitch"] = request.POST.get("hotSwitch")
  424. setConf["hotWaterMax"] = request.POST.get("hotWaterMax")
  425. setConf["hotWaterMin"] = request.POST.get("hotWaterMin")
  426. setConf["coldSwitch"] = request.POST.get("coldSwitch")
  427. setConf["coldWaterMax"] = request.POST.get("coldWaterMax")
  428. setConf["coldWaterMin"] = request.POST.get("coldWaterMin")
  429. setConf["lockTime"] = request.POST.get("lockTime")
  430. setConf["payModuleSwitch"] = request.POST.get("payModuleSwitch")
  431. setConf["cupModule"] = cupModule
  432. setConf["lightSwitch"] = request.POST.get("lightSwitch")
  433. setConf["leftCupSwitch"] = request.POST.get("leftCupSwitch", 1)
  434. self.set_dev_paras(setConf)
  435. def set_device_function(self, request, lastSetConf):
  436. """
  437. 设置设备功能 重启 重置
  438. :param request:
  439. :param lastSetConf:
  440. :return:
  441. """
  442. if request.POST.get("reboot"):
  443. self.reboot()
  444. if request.POST.get("recover"):
  445. self.recovery()
  446. def get_port_status(self, force = False):
  447. pass
  448. def async_update_portinfo_from_dev(self):
  449. pass
  450. def start_device(self, package, openId, attachParas):
  451. """
  452. 根据套餐名称 反推出能加工套餐名称的 出水口
  453. :param package:
  454. :param openId:
  455. :param attachParas:
  456. :return:
  457. """
  458. packageName = package.get("name", "")
  459. # 获取当前的端口加工模式
  460. devCache = Device.get_dev_control_cache(self._device["devNo"])
  461. portList = list()
  462. for port, info in devCache.items():
  463. if isinstance(info, dict) and "makeDrinkMode" in info:
  464. modeName = self.DRINK_MOD.get(info.get("makeDrinkMode"))
  465. if modeName == packageName:
  466. portList.append(int(port)-1)
  467. try:
  468. needPort = min(portList)
  469. except Exception as e:
  470. needPort = None
  471. if needPort is None or (needPort < 0 or needPort > 7):
  472. raise ServiceException({"result": 2, "description": u"设备暂不支持该饮料模式,请联系经销商!"})
  473. # 确定了端口之后,下发做杯
  474. result = self.remote_cup(needPort)
  475. attachParas.update({"chargeIndex": str(needPort)})
  476. finishedTime = int(time.time())
  477. result["finishedTime"] = finishedTime
  478. user = MyUser.objects.filter(openId=openId, groupId=self._device["groupId"]).first()
  479. managerialOpenId = user.managerialOpenId if user else ""
  480. group = Group.get_group(self._device["groupId"])
  481. kwargs = {
  482. "title": u"\\n\\n模式选择:\\t\\t{mod}\\n\\n设备编号:\\t\\t{logicalCode}\\n\\n服务地址:\\t\\t{group}".format(
  483. mod=packageName,
  484. logicalCode=self._device["logicalCode"],
  485. group=group["address"],
  486. ),
  487. "service": u"您的饮料正在{port}号口加工,请稍后".format(port=needPort+1),
  488. "finishTime": str(datetime.datetime.now())[:19],
  489. 'remark': u'谢谢您的支持'
  490. }
  491. task_caller('report_to_user_via_wechat', openId=managerialOpenId, dealerId=self._device["ownerId"],
  492. templateName="service_complete", **kwargs)
  493. return result