123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781 |
- # -*- coding: utf-8 -*-
- # !/usr/bin/env python
- import datetime
- import random
- import logging
- import binascii
- import time
- from typing import TYPE_CHECKING
- from apps.web.core.adapter.base import SmartBox, fill_2_hexByte, reverse_hex
- from apps.web.core.networking import MessageSender
- from apps.web.core.exceptions import ServiceException
- from apps.web.constant import Const, DeviceCmdCode, MQTT_TIMEOUT
- from apps.web.device.models import Device
- from apps.web.user.models import ConsumeRecord
- from apilib.monetary import VirtualCoin
- logger = logging.getLogger(__name__)
- if TYPE_CHECKING:
- pass
- class ChargeModeMap(object):
- TIME_QUOTA = 1
- POWER_QUOTA = 2
- ELEC_QUOTA = 3
- FREE_QUOTA = 4
- INTERVAL_QUOTA = 5
- class PortStatusCode(object):
- DEV_WORK_STATUS_IDLE = 0
- DEV_WORK_STATUS_IDLE_POWER_NORMAL_FAULT_RELAY_CONNECT = 1
- DEV_WORK_STATUS_IDLE_FAULT_OVERLOAD_RELAY_CONNECT_NORMAL = 2
- DEV_WORK_STATUS_IDLE_FAULT_OVERLOAD_FAULT_RELAY_CONNECT = 3
- DEV_WORK_STATUS_WORKING = 4
- DEV_WORK_STATUS_WORKING_POWER_NORMAL_FAULT_RELAY_CONNECT = 5
- DEV_WORK_STATUS_WORKING_FAULT_OVERLOAD_RELAY_CONNECT_NORMAL = 6
- DEV_WORK_STATUS_WORKING_FAULT_OVERLOAD_FAULT_RELAY_CONNECT = 7
- DEV_WORK_STATUS_WORKING_COIN = 8
- DEV_WORK_STATUS_WORKING_COIN_POWER_NORMAL_FAULT_RELAY_CONNECT = 9
- DEV_WORK_STATUS_WORKING_COIN_FAULT_OVERLOAD_RELAY_CONNECT_NORMAL = 10
- DEV_WORK_STATUS_WORKING_COIN_FAULT_OVERLOAD_FAULT_RELAY_CONNECT = 11
- class BILLING_TYPE(object):
- """
- 充电方式
- """
- TIME = "time"
- ELEC = "elec"
- POWER = "power"
- FREE = "free"
- INTERVAL_QUOTA = "interval_quota"
- class ChargingBeiSiYunBox(SmartBox):
- def _encrypt_func(self, bArray, kArray, r, en=True):
- """
- :param bArray: 加密的字节数组
- :param kArray: 加密的字节数组 参与加密
- :param r: 加密的随机字符 0-255 单字节
- :param en: 是否为加密 True = 加密 False = 解密
- """
- kenLen = 10
- result = bytearray()
- for i in range(len(bArray)):
- temp_char = bArray[i]
- s = i % kenLen + 1
- if s == kenLen:
- s = 0
- else:
- s = s
- k = kArray[s]
- if en:
- rc = (temp_char + k + r) % 256
- else:
- rc = (temp_char - k - r) % 256
- result.insert(i, rc)
- # print("[encrypt_func] result = {}, hex result = {}".format(result, binascii.hexlify(result)))
- return result
- def _send_mqtt(self, funCode, data=None, cmd=None, timeout=MQTT_TIMEOUT.NORMAL):
- """
- 发送数据到mqtt服务器
- :param funCode:
- :param data:
- :param cmd:
- :param timeout:
- :return:
- """
- if cmd is None:
- cmd = DeviceCmdCode.OPERATE_DEV_SYNC
- if data is None:
- data = "00"
- result = MessageSender.send(device=self.device, cmd=cmd, payload={
- "IMEI": self.device.devNo,
- "funCode": funCode,
- "data": data
- }, timeout=timeout)
- if "rst" in result and result.get("rst") != 0:
- if result.get("rst") == -1:
- raise ServiceException({"result": 2, "description": u"网络故障,请重新试试"})
- if result.get("rst") == 1:
- raise ServiceException({"result": 2, "description": u"充电桩无响应,请稍后再试试"})
- return result
- def _start_remote(self, port, method, orderType, balance, orderNo, maxTime=0, spendMoney=0, other=0):
- portHex = fill_2_hexByte(hex(int(port)), 2)
- methodHex = fill_2_hexByte(hex(int(method)), 2)
- orderTypeHex = fill_2_hexByte(hex(int(orderType)), 2)
- balanceHex = fill_2_hexByte(hex(int(balance)), 4)
- orderNoHex = fill_2_hexByte(hex(int(orderNo)), 10)
- maxTimeHex = fill_2_hexByte(hex(int(maxTime)), 2)
- spendMoneyHex = fill_2_hexByte(hex(int(spendMoney)), 4)
- otherHex = fill_2_hexByte(hex(int(other)), 4)
- data = portHex + methodHex + orderTypeHex + balanceHex + orderNoHex + maxTimeHex + spendMoneyHex + otherHex
- result = self._send_mqtt("A2", data=data)
- # deviceVersion = int(result["data"][2:8], 16)
- # port = int(result["data"][8:10], 16)
- # orderNo = int(result["data"][10:20], 16)
- # infoDict = {
- # "deviceVersion": deviceVersion,
- # "port": port,
- # "orderNo": orderNo
- # }
- return result
- def _update_charge_balance(self, port, balance, other=0):
- portHex = fill_2_hexByte(hex(int(port)), 2)
- balanceHex = fill_2_hexByte(hex(int(balance)), 4)
- otherHex = fill_2_hexByte(hex(int(other), 4))
- data = portHex + balanceHex + otherHex
- result = self._send_mqtt("A3", data=data)
- deviceVersion = int(result["data"][2:8], 16)
- port = int(result["data"][8:10], 16)
- orderNo = int(result["data"][10:20], 16)
- newBalance = int(result["data"][20:24], 16) / 100
- infoDict = {
- "deviceVersion": deviceVersion,
- "port": port,
- "orderNo": orderNo,
- "newBalance": newBalance,
- }
- return infoDict
- def _stop_remote(self, port, other=0):
- portHex = fill_2_hexByte(hex(int(port)), 2)
- otherHex = fill_2_hexByte(hex(int(other)), 4)
- data = portHex + otherHex
- result = self._send_mqtt("A4", data=data)
- deviceVersion = int(result["data"][2:8], 16)
- port = int(result["data"][8:10], 16)
- orderNo = int(result["data"][10:20], 16)
- chargeStatus = int(result["data"][20:22], 16)
- usedElec = int(result["data"][22:28], 16) / 1000
- usedMoney = int(result["data"][28:32], 16) / 100
- self._ack(port)
- infoDict = {
- "deviceVersion": deviceVersion,
- "port": port,
- "orderNo": orderNo,
- "chargeStatus": chargeStatus,
- "usedElec": usedElec,
- "usedMoney": usedMoney,
- }
- return infoDict
- def _ack(self, port):
- portHex = fill_2_hexByte(hex(int(port)), 2)
- data = portHex + "01"
- self._send_mqtt("AA", data=data, cmd=DeviceCmdCode.OPERATE_DEV_NO_RESPONSE)
- def _check_MCU_code(self):
- result = self._send_mqtt("B0", data="00")
- deviceVersion = int(result["data"][2:8], 16)
- deviceCode = int(result["data"][8:], 16)
- infoDict = {
- "deviceVersion": deviceVersion,
- "deviceCode": deviceCode
- }
- return infoDict
- def _check_MCU_temperature(self):
- result = self._send_mqtt("B1", data="00")
- deviceVersion = int(result["data"][2:8], 16)
- temperature = int(result["data"][8:], 16)
- infoDict = {
- "deviceVersion": deviceVersion,
- "temperature": temperature
- }
- return infoDict
- def _relay_control(self, relay, control):
- relayHex = fill_2_hexByte(hex(int(relay)), 2)
- controlHex = fill_2_hexByte(hex(int(control)), 2)
- data = relayHex + controlHex
- self._send_mqtt("B2", data=data, cmd=DeviceCmdCode.OPERATE_DEV_NO_RESPONSE)
- def _update_device(self, typeCode, code):
- typeCodeHex = fill_2_hexByte(hex(int(typeCode)), 2)
- codeHex = fill_2_hexByte(hex(int(code)), 6)
- data = typeCodeHex + codeHex
- self._send_mqtt("B3", data=data, cmd=DeviceCmdCode.OPERATE_DEV_NO_RESPONSE)
- def _restart_device(self):
- self._send_mqtt("B4", data="00", cmd=DeviceCmdCode.OPERATE_DEV_NO_RESPONSE)
- def _set_sound(self, sound):
- self._send_mqtt("B5", data=sound, cmd=DeviceCmdCode.OPERATE_DEV_NO_RESPONSE)
- def _remote_set_device_function_parameter(self, infoDic):
- minPowerHex = fill_2_hexByte(hex(int(float(infoDic.get("minPower")) / 0.2)), 2)
- checkTimeHex = fill_2_hexByte(hex(int(infoDic.get("checkTime"))), 2)
- powerFailureTimeHex = fill_2_hexByte(hex(int(infoDic.get("powerFailureTime")) / 5), 2)
- checkAutoStopHex = fill_2_hexByte(hex(int(infoDic.get("checkAutoStop"))), 2)
- floatTimeHex = fill_2_hexByte(hex(int(infoDic.get("floatTime"))), 2)
- price = fill_2_hexByte(hex(int(float(infoDic.get("price")) * 100)), 4)
- overloadPowerHex = fill_2_hexByte(hex(int(infoDic.get("overloadPower"))), 4)
- onceChargeTimeHex = fill_2_hexByte(hex(int(float(infoDic.get("onceChargeTime")) / 5)), 2)
- temperatureTresholdHex = fill_2_hexByte(hex(int(infoDic.get("checkTime"))), 2)
- powerPrice = infoDic.get("powerPrice")
- if len(powerPrice) < 10:
- i = len(powerPrice)
- while i < 10:
- powerPrice.update({str(i): {u'max': 0xffff, u'price': 655.35}})
- i += 1
- powerPriceHex = ""
- for i in range(10):
- max = powerPrice[str(i)]["max"]
- sectionPrice = int(powerPrice[str(i)]["price"] * 100)
- powerPriceHex = powerPriceHex + fill_2_hexByte(hex(int(max))) + fill_2_hexByte(hex(sectionPrice))
- data = minPowerHex + checkTimeHex + powerFailureTimeHex + checkAutoStopHex + floatTimeHex + \
- price + overloadPowerHex + onceChargeTimeHex + temperatureTresholdHex + powerPriceHex
- self._send_mqtt("B6", data=data, cmd=DeviceCmdCode.OPERATE_DEV_NO_RESPONSE)
- def _remote_get_dev_setting(self):
- result = self._send_mqtt("B7", data="00")
- data = result.get("data")[10:]
- minPower = int(data[0:2], 16) * 0.2
- checkTime = int(data[2:4], 16)
- powerFailureTime = int(data[4:6], 16) * 5
- checkAutoStop = int(data[6:8], 16)
- floatTime = int(data[8:10], 16)
- price = float(int(data[10:14], 16)) / 100
- overloadPower = int(data[14:18], 16)
- onceChargeTime = int(data[18:20], 16) * 5
- temperatureTreshold = int(data[20:22], 16)
- powerPriceHex = data[22:]
- packages = []
- for i in range(10):
- max = int(powerPriceHex[i * 8:i * 8 + 8][:4], 16)
- sectionPrice = float(int(powerPriceHex[i * 8:i * 8 + 8][4:], 16)) / 100
- if max != 65535 and sectionPrice != 6553.55:
- packages.append({"max": max, "price": sectionPrice})
- sound = self.device.otherConf.get('sound')
- billingType = self.device.otherConf.get('billingType')
- infoDict = {
- "minPower": minPower,
- "checkTime": checkTime,
- "powerFailureTime": powerFailureTime,
- "checkAutoStop": checkAutoStop,
- "floatTime": floatTime,
- "price": price,
- "overloadPower": overloadPower,
- "onceChargeTime": onceChargeTime,
- "temperatureTreshold": temperatureTreshold,
- "packages": packages,
- "sound": sound,
- "billingType": billingType
- }
- return infoDict
- def _get_device_status_info(self):
- result = self._send_mqtt("A6", "00")
- deviceVersion = int(result["data"][2:8], 16)
- typeOfDevice = int(result["data"][8:10], 16)
- other = int(result["data"][10:12], 16)
- portStatus = result["data"][12:]
- if typeOfDevice == 1:
- portNum = 2
- elif typeOfDevice == 2:
- portNum = 10
- elif typeOfDevice == 3:
- portNum = 16
- ii = 0
- portNo = 0
- portStatusDict = {}
- while ii < portNum:
- statusTemp = portStatus[ii * 2:ii * 2 + 2]
- if statusTemp == "00":
- status = {'status': Const.DEV_WORK_STATUS_IDLE,
- "statusCode": PortStatusCode.DEV_WORK_STATUS_IDLE}
- elif statusTemp == "01":
- status = {'status': Const.DEV_WORK_STATUS_FAULT_RELAY_CONNECT,
- "statusCode": PortStatusCode.DEV_WORK_STATUS_IDLE_POWER_NORMAL_FAULT_RELAY_CONNECT}
- elif statusTemp == "02":
- status = {'status': Const.DEV_WORK_STATUS_FAULT_OVERLOAD,
- "statusCode": PortStatusCode.DEV_WORK_STATUS_IDLE_FAULT_OVERLOAD_RELAY_CONNECT_NORMAL}
- elif statusTemp == "03":
- status = {'status': Const.DEV_WORK_STATUS_FAULT_OVERLOAD,
- "statusCode": PortStatusCode.DEV_WORK_STATUS_IDLE_FAULT_OVERLOAD_FAULT_RELAY_CONNECT}
- elif statusTemp == "04":
- status = {'status': Const.DEV_WORK_STATUS_WORKING,
- "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING}
- elif statusTemp == "05":
- status = {'status': Const.DEV_WORK_STATUS_FAULT_RELAY_CONNECT,
- "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_POWER_NORMAL_FAULT_RELAY_CONNECT}
- elif statusTemp == "06":
- status = {'status': Const.DEV_WORK_STATUS_FAULT_OVERLOAD,
- "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_FAULT_OVERLOAD_RELAY_CONNECT_NORMAL}
- elif statusTemp == "07":
- status = {'status': Const.DEV_WORK_STATUS_FAULT_OVERLOAD,
- "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_FAULT_OVERLOAD_FAULT_RELAY_CONNECT}
- elif statusTemp == "08":
- status = {'status': Const.DEV_WORK_STATUS_APPOINTMENT,
- "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_COIN}
- elif statusTemp == "09":
- status = {'status': Const.DEV_WORK_STATUS_FAULT_RELAY_CONNECT,
- "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_COIN_POWER_NORMAL_FAULT_RELAY_CONNECT}
- elif statusTemp == "10":
- status = {'status': Const.DEV_WORK_STATUS_FAULT_OVERLOAD,
- "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_COIN_FAULT_OVERLOAD_RELAY_CONNECT_NORMAL}
- elif statusTemp == "11":
- status = {'status': Const.DEV_WORK_STATUS_FAULT_OVERLOAD,
- "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_COIN_FAULT_OVERLOAD_FAULT_RELAY_CONNECT}
- else:
- status = {'status': Const.DEV_WORK_STATUS_FAULT}
- ii += 1
- portNo += 1
- portStatusDict[str(portNo)] = status
- infoDict = {
- "deviceVersion": deviceVersion,
- "typeOfDevice": typeOfDevice,
- "other": other,
- "portStatusDict": portStatusDict
- }
- return infoDict
- def analyze_event_data(self, data):
- cmdCode = data[0:2]
- if cmdCode == "A4":
- deviceVersion = int(reverse_hex(data[2:8]), 16)
- port = int(data[8:10], 16)
- orderNo = data[10:20],
- reasonCode = int(data[20:22], 16)
- usedElec = int(reverse_hex(data[22:28]), 16) / 1000
- usedMoney = int(reverse_hex(data[28:32]), 16) / 100
- if reasonCode == 1:
- reason = u"浮充开始"
- elif reasonCode == 2:
- reason = u"主动关闭"
- elif reasonCode == 3:
- reason = u"插头拔出"
- elif reasonCode == 4:
- reason = u"充电完成"
- elif reasonCode == 5:
- reason = u"充满自停"
- elif reasonCode == 6:
- reason = u"功率过载"
- elif reasonCode == 7:
- reason = u"电流过载"
- elif reasonCode == 8:
- reason = u"充电失败,检测功率过低"
- elif reasonCode == 9:
- reason = u"温度异常"
- elif reasonCode == 10:
- reason = u"消费用完"
- return {
- "cmdCode": cmdCode,
- "deviceVersion": deviceVersion,
- "port": port,
- "orderNo": orderNo,
- "reasonCode": reasonCode,
- "reason": reason,
- "usedElec": usedElec,
- "usedMoney": usedMoney
- }
- elif cmdCode == "A5":
- deviceCode = int(data[2:8], 16)
- port = int(data[8:10], 16)
- orderNo = int(data[10:20], 16)
- outputVoltage = int(reverse_hex(data[20:24]), 16) / 100
- outputElec = int(reverse_hex(data[24:28]), 16) / 1000
- power = int(reverse_hex(data[28:34]), 16) / 1000
- usedElec = int(reverse_hex(data[34:40]), 16) / 1000
- usedMoney = int(reverse_hex(data[40:44])), 16 / 100
- return {
- "cmdCode": cmdCode,
- "deviceCode": deviceCode,
- "port": port,
- "orderNo": orderNo,
- "outputVoltage": outputVoltage,
- "outputElec": outputElec,
- "power": power,
- "usedElec": usedElec,
- "usedMoney": usedMoney
- }
- elif cmdCode == "A6":
- deviceVersion = int(data[2:8], 16)
- typeOfDevice = int(data[8:10], 16)
- other = int(data[10:12], 16)
- portStatus = data[12:]
- if typeOfDevice == 1:
- portNum = 2
- elif typeOfDevice == 2:
- portNum = 10
- elif typeOfDevice == 3:
- portNum = 16
- ii = 0
- portNo = 1
- portStatusDict = {}
- while ii < portNum:
- statusTemp = portStatus[ii * 2:ii * 2 + 2]
- if statusTemp == "00":
- status = {'status': Const.DEV_WORK_STATUS_IDLE,
- "statusCode": PortStatusCode.DEV_WORK_STATUS_IDLE}
- elif statusTemp == "01":
- status = {'status': Const.DEV_WORK_STATUS_FAULT_RELAY_CONNECT,
- "statusCode": PortStatusCode.DEV_WORK_STATUS_IDLE_POWER_NORMAL_FAULT_RELAY_CONNECT}
- elif statusTemp == "02":
- status = {'status': Const.DEV_WORK_STATUS_FAULT_OVERLOAD,
- "statusCode": PortStatusCode.DEV_WORK_STATUS_IDLE_FAULT_OVERLOAD_RELAY_CONNECT_NORMAL}
- elif statusTemp == "03":
- status = {'status': Const.DEV_WORK_STATUS_FAULT_OVERLOAD,
- "statusCode": PortStatusCode.DEV_WORK_STATUS_IDLE_FAULT_OVERLOAD_FAULT_RELAY_CONNECT}
- elif statusTemp == "04":
- status = {'status': Const.DEV_WORK_STATUS_WORKING,
- "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING}
- elif statusTemp == "05":
- status = {'status': Const.DEV_WORK_STATUS_FAULT_RELAY_CONNECT,
- "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_POWER_NORMAL_FAULT_RELAY_CONNECT}
- elif statusTemp == "06":
- status = {'status': Const.DEV_WORK_STATUS_FAULT_OVERLOAD,
- "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_FAULT_OVERLOAD_RELAY_CONNECT_NORMAL}
- elif statusTemp == "07":
- status = {'status': Const.DEV_WORK_STATUS_FAULT_OVERLOAD,
- "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_FAULT_OVERLOAD_FAULT_RELAY_CONNECT}
- elif statusTemp == "08":
- status = {'status': Const.DEV_WORK_STATUS_WORKING,
- "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_COIN}
- elif statusTemp == "09":
- status = {'status': Const.DEV_WORK_STATUS_FAULT_RELAY_CONNECT,
- "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_COIN_POWER_NORMAL_FAULT_RELAY_CONNECT}
- elif statusTemp == "10":
- status = {'status': Const.DEV_WORK_STATUS_FAULT_OVERLOAD,
- "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_COIN_FAULT_OVERLOAD_RELAY_CONNECT_NORMAL}
- elif statusTemp == "11":
- status = {'status': Const.DEV_WORK_STATUS_FAULT_OVERLOAD,
- "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_COIN_FAULT_OVERLOAD_FAULT_RELAY_CONNECT}
- else:
- status = {'status': Const.DEV_WORK_STATUS_FAULT}
- ii += 1
- portNo += 1
- portStatusDict[str(portNo)] = status
- return {
- "deviceVersion": deviceVersion,
- "typeOfDevice": typeOfDevice,
- "other": other,
- "portStatusDict": portStatusDict
- }
- elif cmdCode == "A7":
- deviceCode = int(data[2:8], 16)
- cardNo = int(data[8:16], 16)
- mode = int(data[16:18], 16)
- port = int(data[18:20], 16)
- return {
- "deviceCode": deviceCode,
- "cardNo": cardNo,
- "mode": mode,
- "port": port
- }
- elif cmdCode == "A8":
- deviceCode = int(data[2:8], 16)
- cardNo = int(data[8:16], 16)
- return {
- "deviceCode": deviceCode,
- "cardNo": cardNo
- }
- elif cmdCode == "AB":
- deviceCode = int(data[2:8], 16)
- port = int(data[8:10], 16)
- coins = int(data[10:14], 16)
- return {
- "deviceCode": deviceCode,
- "port": port,
- "coins": coins
- }
- elif cmdCode == "B8":
- deviceCode = int(data[2:8], 16)
- return {
- "deviceCode": deviceCode
- }
- def _check_package(self, package):
- billingType = self.device.otherConf.get('billingType','time')
- nowTime = int(time.time())
- unit = self.device.otherConf.get('price')
- onceChargeTime = self.device.otherConf.get('onceChargeTime') or self._remote_get_dev_setting()['onceChargeTime']
- onceChargeTime = int(onceChargeTime)
- if unit != 0:
- if billingType == BILLING_TYPE.TIME:
- method = '01'
- needTime = float(package['price']) / float(unit) * 60
- elif billingType == BILLING_TYPE.POWER:
- method = '02'
- needTime = 0
- elif billingType == BILLING_TYPE.ELEC:
- method = '03'
- needTime = package['price'] / float(unit)
- elif billingType == BILLING_TYPE.FREE:
- method = '04'
- needTime = 0
- elif billingType == BILLING_TYPE.INTERVAL_QUOTA:
- method = '05'
- needTime = 0
- else:
- method = '04'
- needTime = 0
- if needTime > onceChargeTime:
- needTime = onceChargeTime
- finishedTime = nowTime + needTime * 60 * 60
- return method, billingType, needTime, finishedTime
- def start_device(self, package, openId, attachParas):
- chargeIndex = attachParas.get("chargeIndex")
- port = int(chargeIndex) - 1
- coins = float(package['price'])
- balance = int(coins * 100)
- if not chargeIndex:
- raise ServiceException({'result': 2, 'description': u'请您选择合适的充电线路'})
- if not openId:
- raise ServiceException({"result": 2, "description": u"本设备暂不支持上分"})
- devStatus = self._get_device_status_info()
- if devStatus["portStatusDict"][chargeIndex]['status'] == Const.DEV_WORK_STATUS_IDLE:
- method, billingType, needTime, finishedTime = self._check_package(package)
- orderType = '01'
- orderNo = attachParas['orderNo'][-10:]
- result = self._start_remote(port, method, orderType, balance, orderNo)
- portDict = {
- 'startTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
- 'status': Const.DEV_WORK_STATUS_WORKING,
- 'finishedTime': finishedTime,
- 'coins': coins,
- 'isStart': True,
- 'orderNo': attachParas['orderNo'],
- 'useType': 'mobile',
- 'orderType': orderType,
- 'openId': openId,
- 'refunded': False,
- 'billingType': billingType,
- }
- if billingType == 'time':
- portDict.update({'needTime': needTime})
- elif billingType == 'elec':
- portDict.update({'needElec': needTime})
- elif billingType == "power":
- portDict.update({'leftMoney': coins})
- Device.update_dev_control_cache(self._device['devNo'], {str(chargeIndex): portDict})
- result["finishedTime"] = finishedTime
- return result
- elif devStatus["portStatusDict"][chargeIndex]['status'] == Const.DEV_WORK_STATUS_WORKING:
- result = self._update_charge_balance(port, balance)
- portDict = {
- "coins": result.get("newBalance")
- }
- Device.update_dev_control_cache(self._device['devNo'], {str(chargeIndex): portDict})
- return result
- else:
- raise ServiceException(
- {'result': 2, 'description': u'车辆未连接,请先连接车辆!'})
- def get_port_status_from_dev(self):
- result = self._get_device_status_info()
- portDict = result["portStatusDict"]
- allPorts, usedPorts, usePorts = self.get_port_static_info(portDict)
- Device.update_dev_control_cache(self._device['devNo'],
- {'allPorts': allPorts, 'usedPorts': usedPorts, 'usePorts': usePorts})
- ctrInfo = Device.get_dev_control_cache(self._device['devNo'])
- for strPort, info in portDict.items():
- if ctrInfo.has_key(strPort):
- ctrInfo[strPort].update({'status': info['status']})
- else:
- ctrInfo[strPort] = info
- Device.update_dev_control_cache(self._device['devNo'], ctrInfo)
- return result
- def set_device_function_param(self, request, lastSetConf):
- minPower = request.POST.get("minPower")
- checkTime = request.POST.get("checkTime")
- powerFailureTime = request.POST.get("powerFailureTime")
- checkAutoStop = request.POST.get("checkAutoStop")
- floatTime = request.POST.get("floatTime")
- price = request.POST.get("price")
- overloadPower = request.POST.get("overloadPower")
- onceChargeTime = request.POST.get("onceChargeTime")
- temperatureTreshold = request.POST.get("temperatureTreshold")
- packages = request.POST.get('packages')
- powerPrice = {}
- for i in range(len(packages)):
- powerPrice[str(i)] = packages[i]
- lastSetConf.update(
- {
- "minPower": minPower,
- "checkTime": checkTime,
- "powerFailureTime": powerFailureTime,
- "checkAutoStop": checkAutoStop,
- "floatTime": floatTime,
- "price": price,
- "overloadPower": overloadPower,
- "onceChargeTime": onceChargeTime,
- "temperatureTreshold": temperatureTreshold,
- "powerPrice": powerPrice,
- }
- )
- self._remote_set_device_function_parameter(lastSetConf)
- billingType = request.POST.get("billingType")
- sound = request.POST.get('sound')
- self.device.update_device_obj(**{
- 'otherConf.billingType': billingType,
- 'otherConf.sound': sound,
- 'otherConf.onceChargeTime': onceChargeTime,
- 'otherConf.price': price
- })
- if sound == '0':
- soundData = 'EO'
- elif sound == '1':
- soundData = 'E1'
- elif sound == '2':
- soundData = 'E2'
- elif sound == '3':
- soundData = 'E3'
- elif sound == '4':
- soundData = 'E4'
- elif sound == '5':
- soundData = 'E5'
- elif sound == '6':
- soundData = 'E6'
- elif sound == '7':
- soundData = 'E7'
- self._set_sound(soundData)
- def get_dev_setting(self):
- result = self._remote_get_dev_setting()
- return result
- def stop_charging_port(self, port=None):
- if not port:
- raise ServiceException({"result": 2, "description": u"请选择需要结束的充电端口"})
- return self._stop_remote(port)
- def _response_data(self, cmd, data):
- self._send_mqtt(cmd, data)
- def get_port_status(self, force=False):
- if force:
- return self.get_port_status_from_dev()["portStatusDict"]
- ctrInfo = Device.get_dev_control_cache(self.device.devNo)
- if 'allPorts' in ctrInfo and ctrInfo['allPorts'] > 0:
- allPorts = ctrInfo['allPorts']
- else:
- allPorts = 10
- statusDict = {}
- for ii in range(allPorts):
- tempDict = ctrInfo.get(str(ii + 1), {})
- if tempDict.has_key('status'):
- statusDict[str(ii + 1)] = {'status': tempDict.get('status')}
- elif tempDict.has_key('isStart'):
- if tempDict['isStart']:
- statusDict[str(ii + 1)] = {'status': Const.DEV_WORK_STATUS_WORKING}
- else:
- statusDict[str(ii + 1)] = {'status': Const.DEV_WORK_STATUS_IDLE}
- else:
- statusDict[str(ii + 1)] = {'status': Const.DEV_WORK_STATUS_IDLE}
- return statusDict
- def active_deactive_port(self, chargeIndex, active):
- if active:
- raise ServiceException({'result': 2, 'description': u'该设备不支持直接打开端口'})
- port = int(chargeIndex) - 1
- self.stop_charging_port(str(port))
- devInfo = Device.get_dev_control_cache(self._device['devNo'])
- portCtrInfo = devInfo.get(str(chargeIndex), {})
- portCtrInfo.update({'isStart': False, 'status': Const.DEV_WORK_STATUS_IDLE, 'needTime': 0, 'leftTime': 0,
- 'endTime': datetime.datetime.now().strftime(Const.DATETIME_FMT)})
- newValue = {str(chargeIndex): portCtrInfo}
- Device.update_dev_control_cache(self._device['devNo'], newValue)
- def get_port_info(self, chargeIndex):
- port = int(chargeIndex) - 1
- portHex = fill_2_hexByte(hex(int(port)), 2)
- result = self._send_mqtt('A5', data=portHex)
- data = result['data']
- deviceCode = int(reverse_hex(data[2:8]), 16)
- port = int(data[8:10], 16)
- orderNo = int(reverse_hex(data[10:20]), 16)
- outputVoltage = float(int(reverse_hex(data[20:24]), 16)) / 100
- outputElec = float(int(reverse_hex(data[24:28]), 16)) / 1000
- power = float(int(reverse_hex(data[28:34]), 16)) / 1000
- usedElec = float(int(reverse_hex(data[34:40]), 16)) / 1000
- usedMoney = float(int(reverse_hex(data[40:42]), 16)) / 100
- cacheInfo = Device.get_dev_control_cache(self.device.devNo)
- lineInfo = cacheInfo[chargeIndex]
- startTime = datetime.datetime.strptime(lineInfo['startTime'], '%Y-%m-%d %H:%M:%S')
- startTime = int(time.mktime(startTime.timetuple()))
- nowTime = time.time()
- data = {"port": chargeIndex, "power": power, 'elec': usedElec, 'consumeMoney': usedMoney, \
- 'outputVoltage': outputVoltage, 'outputElec': outputElec}
- if "needTime" in lineInfo:
- needTime = lineInfo['needTime']
- leftTime = int(needTime - (nowTime - startTime) / 60)
- data.update({"needTime":needTime,"leftTime":leftTime})
- elif "needElec" in lineInfo:
- needElec = lineInfo['needElec']
- leftElec = float(needElec) - usedElec
- data.update({"needElec": needElec, "leftElec": leftElec})
- elif "leftMoney" in lineInfo:
- leftMoney = float(lineInfo['leftMoney']) - usedMoney
- data.update({"leftMoney": leftMoney})
- return data
|