123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823 |
- # -*- coding: utf-8 -*-
- """
- --- 电量修改 zjl
- --- 主要修改功能 增加电量模式 根据不通的套餐单位 决定当前的计费模式
- """
- import datetime
- import logging
- import time
- from apilib.utils_datetime import timestamp_to_dt
- from apps.web.constant import Const, DeviceCmdCode, MQTT_TIMEOUT
- from apps.web.core.adapter.base import SmartBox, fill_2_hexByte
- from apps.web.core.exceptions import ServiceException
- from apps.web.core.networking import MessageSender
- from apps.web.dealer.models import Dealer
- from apps.web.device.models import Device
- from apps.web.core.device_define.baojia import CMD_CODE, DEFAULT_PARAM, BILLING_TYPE
- from apps.web.user.models import MyUser
- logger = logging.getLogger(__name__)
- class ChargingBAOJIABox(SmartBox):
- CHARGE_CARD_REASON_MAP = {
- "00": u"充值成功",
- "01": u"读卡充值",
- "02": u"卡片未注册",
- "03": u"读卡器故障",
- "04": u"主板故障"
- }
- PORT_STATUS_MAP = {
- "01": Const.DEV_WORK_STATUS_IDLE,
- "02": Const.DEV_WORK_STATUS_WORKING,
- "03": Const.DEV_WORK_STATUS_FORBIDDEN,
- "04": Const.DEV_WORK_STATUS_FAULT
- }
- FINISHED_REASON_MAP = {
- '00': u'购买的充电时间或电量用完了。',
- '01': u'可能是插头被拔掉,或者电瓶已经充满。系统判断为异常断电,由于电瓶车充电器种类繁多,可能存在误差。如有问题,请您及时联系商家协助解决问题并恢复充电。',
- '02': u'恭喜您!电池已经充满电!',
- '03': u'警告!您的电池超功率,已经停止充电,为了公共安全,不建议您在该充电桩充电!提醒您,为了安全大功率的电池不要放入楼道、室内等位置充电哦',
- '04': u'远程断电。',
- '0B': u'设备或端口出现问题,为了安全起见,被迫停止工作。建议您根据已经充电的时间评估是否需要到现场换到其他端口充电。'
- }
- def __init__(self, device):
- super(ChargingBAOJIABox, self).__init__(device)
- @staticmethod
- def _parse_card_09(data):
- """
- 09命令 设备至模块 在线查询卡余额
- :return:
- """
- cardNoHex = data[6:14]
- return {"cardNo": str(int(cardNoHex, 16)), "cardNoHex": cardNoHex}
- @staticmethod
- def _parse_card_13(data):
- """
- 通知后台线下卡的消费
- :param data:
- :return:
- """
- cardNoHex = data[6:14]
- payType = data[14:16]
- money = int(data[16:18], 16) / 10.0
- cardType = data[18:20]
- balance = int(data[20:24], 16) / 10.0
- return {
- "cardNo": str(int(cardNoHex, 16)),
- "payType": payType,
- "money": money,
- "cardType": cardType,
- "balance": balance,
- "cardNoHex": cardNoHex
- }
- @staticmethod
- def _parse_card_27(data):
- """
- ID 卡消费确认
- :param data:
- :return:
- """
- portStr = str(int(data[6:8], 16))
- cardNo = str(int(data[8:16], 16))
- money = int(data[16:20], 16) / 10.0
- _time = int(data[20:24], 16)
- elec = int(data[24:28], 16) / 100.0
- return {
- "portStr": portStr,
- "cardNo": cardNo,
- "money": money,
- "time": _time,
- "elec": elec
- }
- @staticmethod
- def _parse_card_12(data):
- """
- 解析远程卡充值的情况
- :param data:
- :return:
- """
- cardNo = str(int(data[6:14], 16))
- money = str(int(data[16:20], 16) / 10.0)
- balance = str(int(data[20:24], 16) / 10.0)
- res = data[24:26]
- reasonCode = data[26:28]
- reason = ChargingBAOJIABox.CHARGE_CARD_REASON_MAP.get(reasonCode, "")
- return {
- "cardNo": cardNo,
- "money": money,
- "balance": balance,
- "res": res,
- "reason": reason
- }
- @staticmethod
- def _parse_port_status_21(data):
- """
- 解析上报的21数据 端口实时状态
- :param data:
- :return:
- """
- portNum = int(data[6:8], 16)
- portStatusDict = dict()
- tempData = data[8:]
- while portNum:
- tempPort = str(int(tempData[:2], 16))
- tempStatus = ChargingBAOJIABox.PORT_STATUS_MAP.get(tempData[2:4], Const.DEV_WORK_STATUS_IDLE)
- tempTime = int(tempData[4:8], 16)
- tempPower = int(tempData[8:12], 16)
- tempElec = int(tempData[12:16], 16) * 0.01
- portStatusDict[tempPort] = {
- "status": tempStatus,
- "power": tempPower,
- }
- if tempTime:
- portStatusDict[tempPort].update({"leftTime": tempTime})
- if tempElec:
- portStatusDict[tempPort].update({"leftElec": tempElec})
- portNum -= 1
- tempData = tempData[16:]
- return portStatusDict
- @staticmethod
- def _parse_finished(data):
- """
- 解析结束上报过来的是数据
- :param data:
- :return:
- """
- portStr = str(int(data[6:8], 16))
- leftMoney = int(data[8:12], 16) / 10.0
- leftTime = int(data[12:16], 16)
- leftElec = int(data[16:20], 16) / 100.0
- reasonCode = data[20:22]
- return {
- "portStr": portStr,
- "leftMoney": leftMoney,
- "leftTime": leftTime,
- "leftElec": leftElec,
- "reasonCode": reasonCode,
- "reason": ChargingBAOJIABox.FINISHED_REASON_MAP.get(reasonCode, u"未知原因")
- }
- @staticmethod
- def _check_charge_package(package):
- """
- 检查 套餐的配置 目前不支持按电量计费
- :param package:
- :return:
- """
- def _remote_charge_card(self, money):
- """
- # 充值
- :param money:
- :return:
- """
- cardType = "02"
- moneyHex = fill_2_hexByte(hex(int(float(money) * 10)), 4)
- self._send_data("12", cardType + moneyHex, cmd = DeviceCmdCode.OPERATE_DEV_NO_RESPONSE)
- def _restart(self):
- self._send_data("05", "FF01", cmd = DeviceCmdCode.OPERATE_DEV_NO_RESPONSE)
- def _stop(self, port):
- portStr = fill_2_hexByte(hex(int(port)), 2)
- self._send_data("05", portStr + "03", cmd = DeviceCmdCode.OPERATE_DEV_NO_RESPONSE)
- def _get_device_consume_count(self):
- """
- 从设备侧获取 消费总额的统计
- :return:
- """
- result = self._send_data("07", "0000")
- data = result.get("data", "")
- cardFee = int(data[6:10], 16) / 10.0
- coinFee = int(data[10:14], 16)
- return {
- "cardFee": cardFee,
- 'coinFee': coinFee
- }
- def _response_card_balance(self, cardNoHex, balance):
- """
- 回复主板 卡的余额09指令
- :param cardNoHex:
- :param balance:
- :return:
- """
- balanceHex = fill_2_hexByte(hex(int(balance * 10)), 4)
- self._send_data("09", cardNoHex + balanceHex, cmd = DeviceCmdCode.OPERATE_DEV_NO_RESPONSE)
- def _response_card_consume(self, cardNoHex, cardMoney, cardType, status):
- """
- 回复主板 卡的消费的13指令
- :param cardNoHex:
- :param cardMoney:
- :param cardType:
- :param status:
- :return:
- """
- cardMoneyHex = fill_2_hexByte(hex(int(cardMoney * 10)), 4)
- sendData = cardNoHex + cardMoneyHex + cardType + status
- self._send_data("13", sendData, cmd = DeviceCmdCode.OPERATE_DEV_NO_RESPONSE)
- def _send_data(self, funCode, data = None, cmd = None, timeout = MQTT_TIMEOUT.NORMAL):
- """
- 发送数据到mqtt服务器
- :param funCode:
- :param cmd:
- :param data:
- :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
- @staticmethod
- def _suit_package_by_unit(package):
- goodsUnit = package.get("unit")
- if goodsUnit not in [u"度", u"分钟", u"小时", u"秒"]:
- raise ServiceException({"result": 2, "description": "套餐单位错误,联系设备经销商"})
- coins = float(package.get("coins"))
- goodsNum = float(package.get("time"))
- billingType = BILLING_TYPE.TIME
- _time = 0xFFFF
- elec = 0xFFFF
- if goodsUnit == u"秒":
- _time = goodsNum / 60.0
- elif goodsUnit == u"分钟":
- _time = goodsNum
- elif goodsUnit == u"小时":
- _time = goodsNum * 60
- else:
- elec = goodsNum * 100
- billingType = BILLING_TYPE.ELEC
- return coins, _time, elec, billingType
- def remote_charge_card(self, price, rechargeRecord=None):
- """
- 对接上层接口,发卡机
- :param price: 充值的金额
- :param rechargeRecord: 充值记录
- :return:
- """
- self._remote_charge_card(price)
- def get_port_status_from_dev(self):
- """
- 从设备端获取 端口状态
- :return:
- """
- devInfo = self._send_data("0F", "00")
- data = devInfo['data'][4::]
- result = {}
- portNum = int(data[2:4], 16)
- portData = data[4::]
- ii = 0
- while ii < portNum:
- port = int(portData[ii * 4:ii * 4 + 2], 16)
- statusTemp = portData[ii * 4 + 2:ii * 4 + 4]
- if statusTemp == '01':
- status = {'status': Const.DEV_WORK_STATUS_IDLE}
- elif statusTemp == '02':
- status = {'status': Const.DEV_WORK_STATUS_WORKING}
- elif statusTemp == '03':
- status = {'status': Const.DEV_WORK_STATUS_FORBIDDEN}
- elif statusTemp == '04':
- status = {'status': Const.DEV_WORK_STATUS_FAULT}
- else:
- status = {'status': Const.DEV_WORK_STATUS_IDLE}
- ii += 1
- result[str(port)] = status
- allPorts, usedPorts, usePorts = self.get_port_static_info(result)
- 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 result.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 analyze_event_data(self, data):
- cmdCode = data[4:6]
- if cmdCode == CMD_CODE.DEVICE_SUBMIT_CHARGE_FINISHED_16:
- eventData = self._parse_finished(data)
- eventData.update({"cmdCode": cmdCode})
- return eventData
- elif cmdCode == CMD_CODE.DEVICE_SUBMIT_DEVICE_FAULT_0A:
- port = int(data[6:8], 16)
- errCode = int(data[8:12], 16)
- return {
- 'status': Const.DEV_WORK_STATUS_FAULT,
- 'statusInfo': u'设备故障',
- 'cmdCode': cmdCode,
- 'port': port,
- 'FaultCode': errCode
- }
- # 以下都是宝佳电子 1.7 版本新增的命令
- elif cmdCode == CMD_CODE.CARD_BALANCE_09:
- eventData = self._parse_card_09(data)
- eventData.update({"cmdCode": cmdCode})
- return eventData
- elif cmdCode == CMD_CODE.CARD_CONSUME_13:
- eventData = self._parse_card_13(data)
- eventData.update({"cmdCode": cmdCode})
- return eventData
- elif cmdCode == CMD_CODE.CARD_CONSUME_SURE_27:
- eventData = self._parse_card_27(data)
- eventData.update({"cmdCode": cmdCode})
- return eventData
- elif cmdCode == CMD_CODE.CARD_REMOTE_CHARGE_12:
- eventData = self._parse_card_12(data)
- eventData.update({"cmdCode": cmdCode})
- return eventData
- elif cmdCode == CMD_CODE.PORT_STATUS_21:
- portInfo = self._parse_port_status_21(data)
- eventData = {
- "portInfo": portInfo,
- "cmdCode": cmdCode
- }
- return eventData
- @property
- def isHaveStopEvent(self):
- return True
- def translate_funcode(self, funCode):
- funCodeDict = {
- '01': u'获取端口数量',
- '02': u'获取端口数据',
- '14': u'移动支付',
- '07': u'获取刷卡投币统计数据',
- '15': u'获取设备端口详情',
- '0F': u'获取端口状态',
- '0C': u'端口锁操作',
- '0D': u'端口开关',
- '1E': u'获取设备设置',
- '18': u'设置设备参数',
- '10': u'回复卡余额',
- }
- return funCodeDict.get(funCode, '')
- def translate_event_cmdcode(self, cmdCode):
- cmdDict = {
- '06': u'充电结束',
- '16': u'充电结束',
- '0A': u'故障',
- '10': u'刷卡上报',
- '20': u'启动设备',
- }
- return cmdDict.get(cmdCode, '')
- def test(self, coins):
- hexElec = fill_2_hexByte(hex(0), 4)
- hexPort = fill_2_hexByte(hex(1), 2)
- hexCoins = fill_2_hexByte(hex(1))
- hexTime = fill_2_hexByte(hex(60))
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': self._device['devNo'], "funCode": '14',
- 'data': hexPort + hexCoins + hexTime + hexElec})
- return devInfo
- def stop(self, port = None):
- if not port:
- raise ServiceException({"result": 0, "description": u"请指定停止端口"})
- self._stop(port)
- def start_device(self, package, openId, attachParas):
- """
- 启动函数 分不同的启动方式
- 目前主板暂时不支持 按电量计费 仅支持按时间计费
- :param package:
- :param openId:
- :param attachParas:
- :return:
- """
- if attachParas is None:
- raise ServiceException({'result': 2, 'description': u'请您选择合适的充电线路、电池类型信息'})
- if "chargeIndex" not in attachParas:
- raise ServiceException({'result': 2, 'description': u'请您选择合适的充电线路'})
- portStr = attachParas.get("chargeIndex")
- coins, _time, elec, billingType = self._suit_package_by_unit(package)
- portHex = "{:0>2X}".format(int(portStr))[:2]
- moneyHex = "{:0>4X}".format(int(coins*10))[:4]
- timeHex = "{:0>4X}".format(int(_time))[:4]
- elecHex = "{:0>4X}".format(int(elec))[:4]
- result = self._send_data("14", portHex + moneyHex + timeHex + elecHex, timeout=MQTT_TIMEOUT.START_DEVICE)
- resultCode = result.get("data", "")[8:10]
- if resultCode != "01":
- raise ServiceException({'result': 2, 'description': u'充电桩启动失败,您的金币还在,请换个充电口试试'})
- start_timestamp = int(time.time())
- otherConf = self.device.get("otherConf", dict())
- refundProtection = otherConf.get("refundProtection", DEFAULT_PARAM.DEFAULT_REFUND_PROTECTION)
- refundProtectionTime = otherConf.get("refundProtectionTime", DEFAULT_PARAM.DEFAULT_REFUND_PROTECTION_TIME)
- lowPowerDetectionSwitch = otherConf.get("lowPowerDetectionSwitch", DEFAULT_PARAM.DEFAULT_LOW_POWER_SWITCH)
- lowPowerDetectionTime = otherConf.get("lowPowerDetectionTime", DEFAULT_PARAM.DEFAULT_LOW_POWER_TIME)
- lowPowerDetectionPower = otherConf.get("lowPowerDetectionPower", DEFAULT_PARAM.DEFAULT_LOW_POWER)
- portDict = {
- 'startTime': timestamp_to_dt(start_timestamp).strftime('%Y-%m-%d %H:%M:%S'),
- 'status': Const.DEV_WORK_STATUS_WORKING,
- 'coins': float(coins),
- 'isStart': True,
- 'openId': openId,
- 'refunded': False,
- 'billingType': billingType,
- 'refundProtection': refundProtection,
- 'refundProtectionTime': refundProtectionTime,
- 'vCardId': self._vcard_id,
- # 用户购买的商品量 单位为 度或者分钟
- 'need{}'.format(billingType.capitalize()): _time if billingType == BILLING_TYPE.TIME else elec / 100.0
- }
- finishedTime = start_timestamp + min(86400, _time*60)
- if 'orderNo' in attachParas:
- portDict.update({'orderNo': attachParas['orderNo']})
- portDict.update({
- 'finishedTime': finishedTime
- })
- Device.update_dev_control_cache(self._device['devNo'], {str(portStr): portDict})
- result["finishedTime"] = finishedTime
- # begin: 低功率检测逻辑
- try:
- if not bool(int(lowPowerDetectionSwitch)) or not openId:
- return result
- user = MyUser.objects(openId = openId, groupId = self._device['groupId']).first()
- dealer = Dealer.get_dealer_from_groupId(self._device['groupId'])
- self.notify_low_power_to_user(
- user, dealer, portStr,
- int(lowPowerDetectionTime),
- int(lowPowerDetectionPower)
- )
- except Exception as e:
- logger.error(e)
- # end: 低功率检测逻辑
- return result
- def get_port_info(self, line):
- devCache = Device.get_dev_control_cache(self.device.devNo)
- portCache = devCache.get(str(line), dict())
- billingType = portCache.get("billingType", BILLING_TYPE.TIME)
- portHex = fill_2_hexByte(hex(int(line)), 2)
- result = self._send_data("15", portHex, cmd = self.make_random_cmdcode())
- data = result.get("data", "")
- if data[6:8] == "00":
- return {"port": line, "leftTime": 0, "power": 0, "surp": 0, "elec": 0}
- power = data[12:16]
- if power in ["0000", "FFFF"]:
- power = 0
- else:
- power = int(power, 16)
- if billingType == BILLING_TYPE.TIME:
- leftHex = data[8:12]
- ratio = 1.0
- else:
- leftHex = data[16:20]
- ratio = 100.0
- if leftHex in ["0000", "FFFF"]:
- left = 0
- else:
- left = int(leftHex, 16) / ratio
- surp = int(data[20:24], 16) / 10.0
- responseData = {
- "port": line,
- "power": power,
- "surp": surp,
- "left{}".format(billingType.capitalize()): left
- }
- return responseData
- def get_port_status(self, force = False):
- if force:
- return self.get_port_status_from_dev()
- ctrInfo = Device.get_dev_control_cache(self._device['devNo'])
- statusDict = {}
- if not ctrInfo.has_key('allPorts'):
- self.get_port_status_from_dev()
- ctrInfo = Device.get_dev_control_cache(self._device['devNo'])
- allPorts = ctrInfo.get('allPorts', 10)
- 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}
- allPorts, usedPorts, usePorts = self.get_port_static_info(statusDict)
- Device.update_dev_control_cache(self._device['devNo'],
- {'allPorts': allPorts, 'usedPorts': usedPorts, 'usePorts': usePorts})
- return statusDict
- def lock_unlock_port(self, port, lock = True):
- """
- 禁用/解禁端口
- :param port:
- :param lock:
- :return:
- """
- lockStr = '05' if lock else '06'
- portStr = fill_2_hexByte(hex(int(port)), 2)
- self._send_data("05", portStr + lockStr, cmd = DeviceCmdCode.OPERATE_DEV_NO_RESPONSE)
- if lock:
- Device.update_dev_control_cache(self._device['devNo'],
- {str(port): {'status': Const.DEV_WORK_STATUS_FORBIDDEN}})
- else:
- Device.update_dev_control_cache(self._device['devNo'], {str(port): {'status': Const.DEV_WORK_STATUS_IDLE}})
- def active_deactive_port(self, port, active):
- """
- 停止/激活充电
- :param port:
- :param active:
- :return:
- """
- if not active:
- self._stop(port)
- devInfo = Device.get_dev_control_cache(self._device['devNo'])
- portCtrInfo = devInfo.get(str(port), {})
- portCtrInfo.update({'isStart': False, 'status': Const.DEV_WORK_STATUS_IDLE,
- 'endTime': datetime.datetime.now().strftime(Const.DATETIME_FMT)})
- newValue = {str(port): portCtrInfo}
- Device.update_dev_control_cache(self._device['devNo'], newValue)
- else:
- raise ServiceException({'result': 2, 'description': u'此设备不支持直接打开端口'})
- def get_dev_setting(self):
- """
- 获取设备参数 有些参数从主板上获取 有些参数从数据库获取
- :return:
- """
- result = self._send_data("1E", "00")
- data = result.get("data", "")[6:]
- coinMin = int(data[0:4], 16) # 投币充电时间
- cardMin = int(data[4:8], 16) # 刷卡充电时间
- coinElec = int(data[8:10], 16) # 投币充电电量
- cardElec = int(data[10:12], 16) # 刷卡充电电量
- cst = int(data[12:16], 16) # 刷卡扣费金额
- powerMax1 = int(data[16:20], 16) # 一档功率
- powerMax2 = int(data[20:24], 16) # 二档功率
- powerMax3 = int(data[24:28], 16) # 三档功率
- powerMax4 = int(data[28:32], 16) # 四档功率
- power2Ti = int(data[32:34], 16) # 二档百分比
- power3Ti = int(data[34:36], 16) # 三档百分比
- power4Ti = int(data[36:38], 16) # 四档百分比
- spRecMon = int(data[38:40], 16) # 余额回收开关
- spFullEmpty = int(data[40:42], 16) # 断电自停
- fullPowerMin = int(data[42:44], 16) # 浮充功率(主板判断充满电功率)
- fullChargeTime = int(data[44:46], 16) # 浮充时间(充满后继续充电时间)
- elecTimeFirst = int(data[46:48], 16) # 是否显示剩余电量(0显示时间/1显示电量)
- # 下面的6个参数都是配置在服务器侧,不通过主板,直接服务器保存
- otherConf = self.device.get("otherConf", dict())
- # 计费方式: 目前主板没有计费方式的开关 先保存到服务器一侧
- billingType = otherConf.get("billingType", DEFAULT_PARAM.DEFAULT_BILLING_TYPE)
- elecFee = otherConf.get("elecFee", DEFAULT_PARAM.DEFAULT_ELEC_FEE)
- # 退费保护: 此开关打开之后,用户充电时间少于一定时间(分钟)全额退费
- refundProtection = otherConf.get("refundProtection", DEFAULT_PARAM.DEFAULT_REFUND_PROTECTION)
- refundProtectionTime = otherConf.get("refundProtectionTime", DEFAULT_PARAM.DEFAULT_REFUND_PROTECTION_TIME)
- # 低功率检测: 用户启动充电后,过一段时间进行检测,检测主板当前充电功率,小于一定功率之后发送微信通知告警用户
- lowPowerDetectionSwitch = otherConf.get("lowPowerDetectionSwitch", DEFAULT_PARAM.DEFAULT_LOW_POWER_SWITCH)
- lowPowerDetectionTime = otherConf.get("lowPowerDetectionTime", DEFAULT_PARAM.DEFAULT_LOW_POWER_TIME)
- lowPowerDetectionPower = otherConf.get("lowPowerDetectionPower", DEFAULT_PARAM.DEFAULT_LOW_POWER)
- resultDict = {
- 'coinMin': coinMin,
- 'cardMin': cardMin,
- 'coinElec': coinElec,
- 'cardElec': cardElec,
- 'cst': cst,
- 'powerMax1': powerMax1,
- 'powerMax2': powerMax2,
- 'powerMax3': powerMax3,
- 'powerMax4': powerMax4,
- 'power2Ti': power2Ti,
- 'power3Ti': power3Ti,
- 'power4Ti': power4Ti,
- 'spRecMon': spRecMon,
- 'spFullEmpty': spFullEmpty,
- 'fullPowerMin': fullPowerMin,
- 'fullChargeTime': fullChargeTime,
- 'elecTimeFirst': elecTimeFirst,
- 'billingType': billingType,
- 'elecFee': elecFee,
- 'refundProtection': int(refundProtection),
- "refundProtectionTime": refundProtectionTime,
- 'lowPowerDetectionTime': lowPowerDetectionTime,
- 'lowPowerDetectionSwitch': int(lowPowerDetectionSwitch),
- 'lowPowerDetectionPower': lowPowerDetectionPower
- }
- # 获取刷卡投币的金额统计信息
- consumeInfo = self._get_device_consume_count()
- resultDict.update(consumeInfo)
- return resultDict
- def set_dev_setting(self, setConf):
- data = ''
- data += fill_2_hexByte(hex(int(setConf['coinMin'])), 4)
- data += fill_2_hexByte(hex(int(setConf['cardMin'])), 4)
- data += fill_2_hexByte(hex(int(setConf['coinElec'])), 2)
- data += fill_2_hexByte(hex(int(setConf['cardElec'])), 2)
- data += fill_2_hexByte(hex(int(setConf['cst'])), 4)
- data += fill_2_hexByte(hex(int(setConf['powerMax1'])), 4)
- data += fill_2_hexByte(hex(int(setConf['powerMax2'])), 4)
- data += fill_2_hexByte(hex(int(setConf['powerMax3'])), 4)
- data += fill_2_hexByte(hex(int(setConf['powerMax4'])), 4)
- data += fill_2_hexByte(hex(int(setConf['power2Ti'])), 2)
- data += fill_2_hexByte(hex(int(setConf['power3Ti'])), 2)
- data += fill_2_hexByte(hex(int(setConf['power4Ti'])), 2)
- data += fill_2_hexByte(hex(int(setConf['spRecMon'])), 2)
- data += fill_2_hexByte(hex(int(setConf['spFullEmpty'])), 2)
- data += fill_2_hexByte(hex(int(setConf['fullPowerMin'])), 2)
- data += fill_2_hexByte(hex(int(setConf['fullChargeTime'])), 2)
- data += fill_2_hexByte(hex(int(setConf['elecTimeFirst'])), 2)
- self._send_data("18", data)
- def set_device_function_param(self, request, lastSetConf):
- """
- 设置 设备参数
- :param request: requestBody
- :param lastSetConf: 缓存数据
- :return:
- """
- coinMin = request.POST.get('coinMin', None)
- cardMin = request.POST.get('cardMin', None)
- coinElec = request.POST.get('coinElec', None)
- cardElec = request.POST.get('cardElec', None)
- cst = request.POST.get('cst', None)
- powerMax1 = request.POST.get('powerMax1', None)
- powerMax2 = request.POST.get('powerMax2', None)
- powerMax3 = request.POST.get('powerMax3', None)
- powerMax4 = request.POST.get('powerMax4', None)
- power2Ti = request.POST.get('power2Ti', None)
- power3Ti = request.POST.get('power3Ti', None)
- power4Ti = request.POST.get('power4Ti', None)
- spRecMon = request.POST.get('spRecMon', None)
- spFullEmpty = request.POST.get('spFullEmpty', None)
- fullPowerMin = request.POST.get('fullPowerMin', None)
- fullChargeTime = request.POST.get('fullChargeTime', None)
- elecTimeFirst = request.POST.get('elecTimeFirst', None)
- billingType = request.POST.get('billingType')
- elecFee = request.POST.get('elecFee')
- refundProtection = request.POST.get('refundProtection')
- refundProtectionTime = request.POST.get("refundProtection")
- lowPowerDetectionTime = request.POST.get('lowPowerDetectionTime')
- lowPowerDetectionSwitch = request.POST.get('lowPowerDetectionSwitch')
- lowPowerDetectionPower = request.POST.get('lowPowerDetectionPower')
- if coinMin:
- lastSetConf.update({'coinMin': int(coinMin)})
- if cardMin:
- lastSetConf.update({'cardMin': int(cardMin)})
- if coinElec:
- lastSetConf.update({'coinElec': int(coinElec)})
- if cardElec:
- lastSetConf.update({'cardElec': int(cardElec)})
- if cst:
- lastSetConf.update({'cst': int(cst)})
- if powerMax1:
- lastSetConf.update({'powerMax1': int(powerMax1)})
- if powerMax2:
- lastSetConf.update({'powerMax2': int(powerMax2)})
- if powerMax3:
- lastSetConf.update({'powerMax3': int(powerMax3)})
- if powerMax4:
- lastSetConf.update({'powerMax4': int(powerMax4)})
- if power2Ti:
- lastSetConf.update({'power2Ti': int(power2Ti)})
- if power3Ti:
- lastSetConf.update({'power3Ti': int(power3Ti)})
- if power4Ti:
- lastSetConf.update({'power4Ti': int(power4Ti)})
- if spRecMon:
- lastSetConf.update({'spRecMon': int(spRecMon)})
- if spFullEmpty:
- lastSetConf.update({'spFullEmpty': int(spFullEmpty)})
- if fullPowerMin:
- lastSetConf.update({'fullPowerMin': int(fullPowerMin)})
- if fullChargeTime:
- lastSetConf.update({'fullChargeTime': int(fullChargeTime)})
- if elecTimeFirst:
- lastSetConf.update({'elecTimeFirst': int(elecTimeFirst)})
- # 设备侧的参数同步到设备
- self.set_dev_setting(lastSetConf)
- otherConf = self.device.get("otherConf", dict())
- if billingType is not None:
- otherConf.update({"billingType": billingType})
- if elecFee is not None:
- otherConf.update({"elecFee": elecFee})
- if refundProtection is not None:
- otherConf.update({"refundProtection": refundProtection})
- if refundProtectionTime is not None:
- otherConf.update({"refundProtectionTim": refundProtectionTime})
- if lowPowerDetectionTime is not None:
- otherConf.update({"lowPowerDetectionTime": lowPowerDetectionTime})
- if lowPowerDetectionSwitch is not None:
- otherConf.update({"lowPowerDetectionSwitch": lowPowerDetectionSwitch})
- if lowPowerDetectionPower is not None:
- otherConf.update({"lowPowerDetectionPower": lowPowerDetectionPower})
- Device.objects.filter(devNo = self.device.devNo).update(otherConf = otherConf)
- Device.invalid_device_cache(self.device.devNo)
- def set_device_function(self, request, lastSetConf):
- if request.POST.get("reboot", False):
- self._restart()
|