hangzhoufulian.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. # coding=utf-8
  2. import binascii
  3. import logging
  4. import time
  5. from apps.web.constant import DeviceCmdCode, MQTT_TIMEOUT, Const
  6. from apps.web.core.adapter.base import SmartBox
  7. from apps.web.core.device_define.hangzhoufulian import FaultMap
  8. from apps.web.core.exceptions import ServiceException
  9. from apps.web.core.networking import MessageSender
  10. from apps.web.device.models import Device
  11. from apps.web.user.models import UniqueUser
  12. logger = logging.getLogger(__name__)
  13. class HZFLChargeBox(SmartBox):
  14. def _send_data(self, funCode, sendData, cmd=DeviceCmdCode.OPERATE_DEV_SYNC, timeout=MQTT_TIMEOUT.NORMAL):
  15. result = MessageSender.send(
  16. device=self.device,
  17. cmd=cmd,
  18. payload={
  19. "IMEI": self._device["devNo"],
  20. "funCode": funCode,
  21. "data": sendData
  22. },
  23. timeout=timeout
  24. )
  25. if "rst" in result:
  26. if result["rst"] == -1:
  27. raise ServiceException({'result': 2, 'description': u'充电桩正在玩命找网络,请稍候再试'})
  28. elif result["rst"] == 1:
  29. raise ServiceException({'result': 2, 'description': u'充电桩暂时无响应,请稍后再试'})
  30. elif result["rst"] == 0:
  31. return result
  32. else:
  33. raise ServiceException({'result': 2, 'description': u'系统错误'})
  34. else:
  35. raise ServiceException({'result': 2, 'description': u'系统错误'})
  36. @staticmethod
  37. def _to_ascii(s):
  38. """
  39. :param s: 原始字符串
  40. :return:
  41. """
  42. return binascii.hexlify(s)
  43. @staticmethod
  44. def _to_str(h):
  45. """
  46. :param h:
  47. :return:
  48. """
  49. return binascii.unhexlify(h)
  50. @staticmethod
  51. def _parse_0100(data):
  52. """
  53. 故障解析
  54. :param data:
  55. :return:
  56. """
  57. faultCode = data[18: 20]
  58. port = int(data[20: 22], 16)
  59. isStop = not bool(int(data[22: 24], 16))
  60. return {
  61. "faultCode": faultCode,
  62. "port": port,
  63. "isStop": isStop,
  64. "fault": FaultMap.get(faultCode, u"未知错误")
  65. }
  66. @staticmethod
  67. def _parse_0102(data):
  68. """端口功率上报"""
  69. # TODO zjl 看下是不是轮询的解析 以及流水号的作用
  70. serialNo = data[18: 28]
  71. power = int(data[28: 32], 16)
  72. port = int(data[32: 34], 16)
  73. return {
  74. "serilaNo": serialNo,
  75. "power": power,
  76. "port": port
  77. }
  78. @staticmethod
  79. def _parse_0105(data):
  80. """充电开始或者结束上报"""
  81. serialNo = data[18: 28]
  82. port = int(data[28: 30], 16)
  83. needTime = int(data[30: 34], 16)
  84. power = int(data[34: 38], 16)
  85. isStop = bool(int(data[38: 40], 16))
  86. return {
  87. "serialNo": serialNo,
  88. "port": port,
  89. "needTime": needTime,
  90. "power": power,
  91. "isStop": isStop
  92. }
  93. @staticmethod
  94. def _parse_000A(data):
  95. pass
  96. @staticmethod
  97. def _parse_0107(data):
  98. """使用电量上报"""
  99. serialNo = data[18: 28]
  100. totalElec = int(data[28: 34], 16)
  101. return {
  102. "serialNo": serialNo,
  103. "totalElec": totalElec
  104. }
  105. def _check_device(self):
  106. """检查设备状态"""
  107. self._send_data("FFFF", "")
  108. def _set_device_power(self, noPower, littlePower, largePower, noPowerTime):
  109. """设置设备功率阈值"""
  110. noPowerHex = "{:0>4X}".format(int(noPower))
  111. littlePowerHex = "{:0>4X}".format(int(littlePower))
  112. largePowerHex = "{:0>4X}".format(int(largePower))
  113. noPowerTimeHex = "{:0>2X}".format(int(noPowerTime))
  114. sendData = noPowerTimeHex + noPowerHex + littlePowerHex + largePowerHex
  115. result = self._send_data("0003", sendData)
  116. if result["data"][18:20] != "01":
  117. raise ServiceException({"result": "2", "description": u"参数设置失败,请重试再试!"})
  118. def _set_device_package(self, coins, powerType, chargeTime):
  119. """设置设备套餐"""
  120. coinsHex = "{:0>2X}".format(coins)
  121. powerTypeHex = "{:0>4X}".format(powerType)
  122. chargeTimeHex = "{:0>4X}".format(chargeTime)
  123. sendData = coinsHex + powerTypeHex + chargeTimeHex
  124. result = self._send_data("0101", sendData)
  125. if result["data"][18:20] != "01":
  126. raise ServiceException({"result": "2", "description": u"参数设置失败,请重试再试!"})
  127. def _start_device(self, orderNo, coins, userId, port):
  128. """启动设备"""
  129. orderNoHex = "{:0>64}".format(self._to_ascii(orderNo))
  130. coinsHex = "{:0>4X}".format(int(coins))
  131. userIdHex = "{:0>8X}".format(int(userId))
  132. portHex = "{:0>2X}".format(port)
  133. sendData = orderNoHex + coinsHex + userIdHex + portHex
  134. result = self._send_data("0004", sendData)
  135. return result
  136. def _get_server_conf(self):
  137. otherConf = self.device.get("otherConf", dict())
  138. return {
  139. "totalElec": otherConf.get("totalElec", 0)
  140. }
  141. def _get_device_conf(self):
  142. return {}
  143. def get_port_status_from_dev(self):
  144. maxPorts = 10
  145. resultDict = dict()
  146. devCache = Device.get_dev_control_cache(self.device.devNo)
  147. for _port in range(1, maxPorts+1):
  148. chargeIndex = str(_port)
  149. portCache = devCache.get(chargeIndex)
  150. if not portCache:
  151. portCache = {"status": Const.DEV_WORK_STATUS_IDLE}
  152. resultDict[chargeIndex] = portCache
  153. allPorts, usedPorts, usePorts = self.get_port_static_info(resultDict)
  154. Device.update_dev_control_cache(
  155. self._device["devNo"],
  156. {
  157. "allPorts": allPorts,
  158. "usedPorts": usedPorts,
  159. "usePorts": usePorts
  160. }
  161. )
  162. return resultDict
  163. def get_port_status(self, force=False):
  164. return self.get_port_status_from_dev()
  165. def get_dev_setting(self):
  166. conf = dict()
  167. serverConf = self._get_server_conf()
  168. deviceConf = self._get_device_conf()
  169. conf.update(serverConf)
  170. conf.update(deviceConf)
  171. return conf
  172. def set_device_function_param(self, request, lastSetConf):
  173. if "noPower" in request.POST:
  174. pass
  175. elif "chargeType" in request.POST:
  176. pass
  177. else:
  178. raise ServiceException({"result": "2", "description": u"不支持的参数设置!"})
  179. def analyze_event_data(self, data):
  180. funCode = data[14:16]
  181. if funCode == "0100":
  182. event = self._parse_0100(data)
  183. elif funCode == "0102":
  184. event = self._parse_0102(data)
  185. elif funCode == "0105":
  186. event = self._parse_0105(data)
  187. elif funCode == "000A":
  188. event = self._parse_000A(data)
  189. elif funCode == "0107":
  190. event = self._parse_0107(data)
  191. else:
  192. logger.error("receice unanalyze event data, data is <{}>, device is <{}>".format(data, self.device.devNo))
  193. return
  194. event["cmdCode"] = funCode
  195. return event
  196. def start_device(self, package, openId, attachParas):
  197. chargeIndex = attachParas.get("chargeIndex")
  198. if not chargeIndex:
  199. raise ServiceException({"result": "2", "description": u"请选择合适的充电线路!"})
  200. port = int(chargeIndex)
  201. orderNo = attachParas["orderNo"]
  202. coins = package["time"]
  203. uniqueUser = UniqueUser.objects.filter(openId=openId).first() # type: UniqueUser
  204. userId = uniqueUser.userId if uniqueUser else 0
  205. result = self._start_device(orderNo=orderNo, coins=coins, userId=userId, port=port)
  206. startTime = int(time.time())
  207. portCache = {
  208. "status": Const.DEV_WORK_STATUS_WORKING,
  209. "isStart": True,
  210. "coins": coins,
  211. "openId": openId,
  212. "orderNo": orderNo,
  213. "startTime": startTime
  214. }
  215. Device.update_dev_control_cache(self.device.devNo, {str(port): portCache})
  216. result["finishedTime"] = (3600 * 12) + startTime
  217. result["startTIme"] = startTime
  218. return result
  219. def check_dev_status(self, attachParas=None):
  220. self._check_device()