123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779 |
- # -*- coding: utf-8 -*-
- # !/usr/bin/env python
- import datetime
- import logging
- import time
- import uuid
- from apilib.monetary import RMB
- from apilib.utils_datetime import timestamp_to_dt
- from apps.web.constant import MQTT_TIMEOUT, DeviceCmdCode, Const
- from apps.web.common.models import TempValues
- from apps.web.core.adapter.base import SmartBox, fill_2_hexByte, start_error_timer
- 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, Group
- from taskmanager.mediator import task_caller
- logger = logging.getLogger(__name__)
- class SendFunCode(object):
- GET_DEV_SETTINGS = "D0"
- SET_DEV_SETTINGS = "D1"
- START_PAY = "D2"
- SYNC_CARD_BALANCE = "D3"
- BEFORE_SYNC_CARD_BALANCE = "D4"
- RESET_DEV = "D5"
- STOP_DEV = "D6"
- SET_GROUP_PW = "DB"
- SET_SEND_CARD = "DC"
- ANSWER_CMD = "DF"
- SET_DEV_DISABLE = "DD"
- class AnalyzeCode(object):
- pass
- class ChargingCY4Box(SmartBox):
- START_TYPE_MAP = {
- "00": "card",
- "01": "mobile",
- "02": "coin"
- }
- STOP_TYPE_MAP = {
- "01": u"充满停止充电",
- "02": u"超出功率停止充电",
- "03": u"充电时间结束停止充电",
- "04": u"远程停止充电"
- }
- NEED_REFUND = ["01", "04"]
- FULL_REFUND_TIME = 180
- MAX_TEMPERATURE = 70
- MIN_TEMPERATURE = -15
- DEFAULT_DISCOUNT = "0"
- REFUND_PRODUCTION_TIME = 5
- VIR_CARD_TIME = 300
- def __init__(self, device):
- super(ChargingCY4Box, self).__init__(device)
- def send_data(self, funCode, data = None, timeout = MQTT_TIMEOUT.NORMAL):
- if data is None:
- data = "00"
- result = MessageSender.send(device = self.device,
- cmd = DeviceCmdCode.OPERATE_DEV_SYNC,
- 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 test(self, coins):
- """
- 测试端口 测试机器启动 固定端口为 01
- """
- hexCoins = fill_2_hexByte(hex(int(float(coins))), 2)
- hexPort = "01"
- data = hexCoins + "0000" + hexPort
- return self.send_data(SendFunCode.START_PAY, data)
- def start_device(self, package, openId, attachParas):
- """
- 指令实例 {"IMEI":"865650042848537", "cmd":210, "funCode": "D2", "data": "1E(金额)0000(预留)0(折扣)3(端口)"}
- """
- # TODO 这个版本先将 续充的入口封死 然后运行一段时间 下次发布的时候就可以彻底将流程归并
- if attachParas is None:
- raise ServiceException({'result': 2, 'description': u'请您选择合适的充电线路、电池类型信息'})
- if "chargeIndex" not in attachParas:
- raise ServiceException({'result': 2, 'description': u'请您选择合适的充电线路'})
- # 参数获取
- price = package.get("price")
- coins = package.get("coins")
- chargeIndex = attachParas.get("chargeIndex")
- devCache = Device.get_dev_control_cache(self.device.devNo)
- portCache = devCache.get(str(chargeIndex))
- # 跟CY进行沟通 由于指令时序的不稳定 去掉续充保证稳定 彻底的将续充的口子封死
- if portCache and "status" in portCache and portCache["status"] != Const.DEV_WORK_STATUS_IDLE:
- raise ServiceException({'result': 2, 'description': u'当前端口正在使用中,请选择其他端口进行充电'})
- # 获取充值订单的ID 用来判断是现金启动还是金币启动
- rechargeRcdId = str(attachParas.get("linkedRechargeRecordId", ""))
- # 首先获取折扣信息 以及端口信息 共一个字节
- hexDiscount = self.get_discount(rechargeRcdId)
- hexPort = hexDiscount + fill_2_hexByte(hex(int(chargeIndex)), 1)
- # 获取下发设备的支付金额, 单位是角 共一个字节
- hexCoins = fill_2_hexByte(hex(int(float(coins * 10))), 2)
- # 如果是虚拟卡(包月卡启动设备),获取经销商设置的虚拟卡启动时间
- timeHex = "0000"
- if self._vcard_id:
- _time = self._device.get("otherConf", dict()).get("vCardTime", self.VIR_CARD_TIME)
- timeHex = fill_2_hexByte(hex(int(_time)))
- # 拼接发送的指令数据域
- dataHex = hexCoins + timeHex + hexPort
- result = self.send_data(SendFunCode.START_PAY, dataHex, timeout = MQTT_TIMEOUT.START_DEVICE)
- data = result.get("data")
- if data[6: 8] != '4F': # 表示成功
- raise ServiceException({'result': 2, 'description': u'启动充电端口失败,您的金币还在,您重新启动试试看'})
- # 非续充 实现续充模式的时候 需要对支付类型限定判断 只能同类型支付模式的续充 即只支持mobile模式的续充
- # 先设置启动时间为0 后续会更新上来
- start_timestamp = int(time.time())
- result['finishedTime'] = start_timestamp + 12 * 60 * 60
- # 由于不会有续充了 重新清理下端口缓存 然后再放入
- Device.clear_port_control_cache(self.device.devNo, chargeIndex)
- # TODO 缓存的数据结构还是保持不变 保证下个版本平稳过渡
- cacheDict = {
- "startTime": timestamp_to_dt(start_timestamp).strftime("%Y-%m-%d %H:%M:%S"),
- "status": Const.DEV_WORK_STATUS_WORKING,
- 'finishedTime': result['finishedTime'],
- "coins": float(coins),
- "price": float(price),
- "openId": openId,
- "consumeType": "mobile",
- "payInfo": [{
- "vCardId": self._vcard_id,
- "coins": float(coins),
- "price": float(price),
- "rechargeRcdId": rechargeRcdId,
- "needTime": 0,
- }],
- "waitD9": True
- }
- Device.update_dev_control_cache(self._device["devNo"], {str(chargeIndex): cacheDict})
- # 如果是正常启动的话
- if openId:
- result["rechargeRcdId"] = rechargeRcdId
- return result
- def apiStartDeviceForCy4(self, record):
- price = record['price'] # int
- discount = record.get('discount', 0) # int
- port = record['port'] # int
- extOrderNo = record.get('extOrderNo', '')
- hexCoins = fill_2_hexByte(hex(int(float(price * 10))), 2)
- timeHex = '0000'
- hexPort = str(discount) + fill_2_hexByte(hex(int(port)), 1)
- dataHex = hexCoins + timeHex + hexPort
- result = self.send_data(SendFunCode.START_PAY, dataHex, timeout=MQTT_TIMEOUT.START_DEVICE)
- data = result.get("data")
- if data[6: 8] != '4F': # 表示成功
- raise ServiceException({"result": 2, "description": u"启动失败,请稍后再试试"})
- cacheDict = {
- 'isAPI': True,
- 'orderNo': 'MOBILE' + str(uuid.uuid4()),
- 'startTime': datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
- 'status': Const.DEV_WORK_STATUS_WORKING,
- 'price': float(price),
- 'coins': float(price),
- 'consumeType': 'mobile',
- 'waitD9': True,
- 'extOrderNo': extOrderNo
- }
- Device.update_dev_control_cache(self._device["devNo"], {str(port): cacheDict})
- return result
- def apiGetDevSettingsFromCy4(self, record):
- result = self.get_dev_setting()
- result.pop('temperature')
- result.pop('disableButton')
- result.pop('discount')
- result.pop('vCardTime')
- return result
- def apiSetDevSettingsFromCy4(self, record):
- self.set_dev_setting(record)
- return {}
- def apiStopChargingPortForCy4(self, record):
- port = record['port']
- self.stop_charging_port(port)
- return {}
- def apiGetPortStatusFromCy4(self, record):
- return self.get_port_status_from_dev()
- def apiGetPortInfoFromCy4(self, record):
- return self.get_port_info(record['port'])
- def get_discount(self, rechargeRcdId):
- """
- 根据启动方式的不通获取不同的折扣 金币启动的不打折 其余的根据设备的折扣而定
- """
- if rechargeRcdId:
- return self._device.get("otherConf", dict()).get("discount", self.DEFAULT_DISCOUNT)
- else:
- return self.DEFAULT_DISCOUNT
- def stop_charging_port(self, port):
- """
- 指令实例 {"IMEI":"865650042848537", "cmd":210, "funCode": "D6", "data": "03(端口)"}
- """
- portHex = fill_2_hexByte(hex(int(port)), 2)
- result = self.send_data(SendFunCode.STOP_DEV, data=portHex)
- data = result.get("data")
- if data[6: 8] != "4F":
- raise ServiceException({"result": 2, "description": u"停止充电失败,请重新试试"})
- return {'port': port}
- def stop(self, port=None):
- """
- :param port:
- :return:
- """
- devCache = Device.get_dev_control_cache(self._device.get("devNo"))
- portCache = devCache.get(str(port), dict())
- if not portCache.get("coins"):
- raise ServiceException({'result': 2, 'description': u'无法停止该端口,请重新试试或者联系经销商'})
- infoDict = self.stop_charging_port(port)
- return infoDict
- @property
- def isHaveStopEvent(self):
- return True
-
- def get_port_status_from_dev(self):
- devCache = Device.get_dev_control_cache(self._device["devNo"])
- allPorts = devCache.get("allPorts", 10)
- portInfo = {}
- for i in xrange(allPorts):
- portStr = str(i+1)
- portTemp = devCache.get(portStr)
- if not portTemp: portTemp = {"status": Const.DEV_WORK_STATUS_IDLE}
- portInfo[portStr] = portTemp
- return portInfo
- def get_temperature(self, tempHex):
- if tempHex[0: 2] == "00":
- temperature = int(tempHex[2: 4], 16)
- else:
- temperature = -int(tempHex[2: 4], 16)
- return temperature
- def parse_port_data(self, data):
- """
- 解析端口上传的数据
- :param data:
- :return:
- """
- # 每一路都空闲的时候,只上报温度 2个字节
- if data[4: 6] == "02":
- portInfo = {str(portNum+1): {"status": Const.DEV_WORK_STATUS_IDLE} for portNum in xrange(10)}
- temperature = self.get_temperature(data[6: 10])
- else:
- statusHex = data[6: 26]
- powerHex = data[26: 66]
- leftHex = data[66: 106]
- temperature = self.get_temperature(data[106: 110])
- portInfo = dict()
- for portNum in xrange(10):
- tempStatus = statusHex[portNum*2: portNum*2+2]
- tempPower = powerHex[portNum*4: portNum*4+4]
- tempLeft = leftHex[portNum*4: portNum*4+4]
- if tempStatus == "00":
- status = Const.DEV_WORK_STATUS_IDLE
- elif tempStatus == "01":
- status = Const.DEV_WORK_STATUS_WORKING
- elif tempStatus == "04":
- status = Const.DEV_WORK_STATUS_FAULT_RELAY_CONNECT
- else:
- logger.error("error port status, device is %s, port is %s, statusHex is %s" % (self._device["devNo"], str(portNum+1), tempStatus))
- status = Const.DEV_WORK_STATUS_IDLE
- power = int(tempPower, 16)
- leftTime = int(tempLeft, 16)
- portInfo[str(portNum+1)] = {"status": status, "power": power}
- if leftTime:
- portInfo[str(portNum+1)].update({"leftTime": leftTime})
- return {"temperature": temperature, "portInfo": portInfo}
- def analyze_event_data(self, data):
- cmdCode = data[2:4]
- #: D7 火警报警
- if cmdCode == 'D7':
- return {'cmdCode': cmdCode}
- #: 状态上报
- elif cmdCode == 'D8':
- resultDict = self.parse_port_data(data)
- # 处理静态端口相关事情
- allPorts, usedPorts, usePorts = self.get_port_static_info(resultDict.get("portInfo"))
- Device.update_dev_control_cache(self._device['devNo'], {'allPorts': allPorts, 'usedPorts': usedPorts, 'usePorts': usePorts})
- resultDict.update({"cmdCode": cmdCode})
- return resultDict
- elif cmdCode == 'D9':
- cardNo = data[6: 14]
- cardBalance = int(data[14:18], 16)
- power = int(data[18:22], 16)
- coins = int(data[22:24], 16)
- result = True if data[24:26] == '00' else False
- port = str(int(data[26:28], 16))
- consumeType = self.START_TYPE_MAP.get(data[28:30])
- needTime = int(data[30:34], 16)
- return {
- 'cardNo': cardNo,
- 'cmdCode': cmdCode,
- 'balance': cardBalance,
- 'power': power,
- 'coins': coins,
- 'result': result,
- 'port': port,
- 'consumeType': consumeType,
- 'needTime': needTime,
- 'data':data
- }
- elif cmdCode == 'DA':
- port = str(int(data[6: 8], 16))
- reasonCode = data[8: 10]
- reason = self.STOP_TYPE_MAP.get(reasonCode)
- elec = int(data[10: 14], 16) / 1000.0
- leftTime = int(data[14: 18], 16)
- return {'port': port, 'reason': reason, 'spendElec': elec, 'leftTime': leftTime, "cmdCode": cmdCode, "reasonCode": reasonCode}
- elif cmdCode == 'D4': # 刷卡充值
- cardNo = data[6: 14]
- cardBalance = int(data[14:18], 16)
- return {
- 'cmdCode': cmdCode,
- 'cardNo': cardNo,
- 'balance': cardBalance
- }
- elif cmdCode == 'D3':
- cardNo = data[6:14]
- cardBalance = int(data[14:18], 16)
- result = True if data[18:20] == 'AA' else False
- sid = str(int(data[20:24], 16))
- return {'cmdCode':cmdCode,'cardNo':cardNo,'balance':cardBalance,'result':result,'sid':sid}
- def get_port_status(self, force = False):
- devCache = Device.get_dev_control_cache(self._device['devNo'])
- statusDict = dict()
- allPorts = devCache.get('allPorts', 10)
- for portNum in range(allPorts):
- tempDict = devCache.get(str(portNum + 1), {})
- if "status" in tempDict:
- statusDict[str(portNum + 1)] = {'status': tempDict.get('status')}
- elif "isStart" in tempDict:
- if tempDict['isStart']:
- statusDict[str(portNum + 1)] = {'status': Const.DEV_WORK_STATUS_WORKING}
- else:
- statusDict[str(portNum + 1)] = {'status': Const.DEV_WORK_STATUS_IDLE}
- else:
- statusDict[str(portNum + 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 active_deactive_port(self, port, active):
- if not active:
- self.stop_charging_port(port)
- else:
- raise ServiceException({'result': 2, 'description': u'此设备不支持直接打开端口'})
- # 获取设备配置参数
- def get_dev_setting(self):
- result = self.send_data(SendFunCode.GET_DEV_SETTINGS)
- confData = result.get("data")[6:]
- time1 = int(confData[0:4], 16)
- time2 = int(confData[4:8], 16)
- time3 = int(confData[8:12], 16)
- time4 = int(confData[12:16], 16)
- powerMax1 = int(confData[16:20], 16)
- powerMax2 = int(confData[20:24], 16)
- powerMax3 = int(confData[24:28], 16)
- powerMax4 = int(confData[28:32], 16)
- elecCheckMin = int(confData[32:34], 16)
- elecCheckTime = int(confData[34:36], 16)
- voice = int(confData[36:38], 16)
- devCache = Device.get_dev_control_cache(self.device.devNo)
- temperature = devCache.get("temperature", 0)
- resultDict = {
- 'time1': time1,
- 'time2': time2,
- 'time3': time3,
- 'time4': time4,
- 'powerMax1': powerMax1,
- 'powerMax2': powerMax2,
- 'powerMax3': powerMax3,
- 'powerMax4': powerMax4,
- 'elecCheckMin': elecCheckMin,
- 'elecCheckTime': elecCheckTime,
- 'voice': voice,
- "temperature": temperature
- }
- resultDict.update({
- "disableButton": int(self._device.get("otherConf", {}).get("disableDevice", False)),
- "discount": self._device.get("otherConf", dict()).get("discount", self.DEFAULT_DISCOUNT),
- "vCardTime": self._device.get("otherConf", dict()).get("vCardTime", self.VIR_CARD_TIME),
- "needBindCard": self._device.get("otherConf", dict()).get("needBindCard", True),
- })
- return resultDict
-
- # 设置设备配置参数
- def set_dev_setting(self, setConf):
- data = ''
- data += fill_2_hexByte(hex(setConf['time1']), 4)
- data += fill_2_hexByte(hex(setConf['time2']), 4)
- data += fill_2_hexByte(hex(setConf['time3']), 4)
- data += fill_2_hexByte(hex(setConf['time4']), 4)
- data += fill_2_hexByte(hex(setConf['powerMax1']), 4)
- data += fill_2_hexByte(hex(setConf['powerMax2']), 4)
- data += fill_2_hexByte(hex(setConf['powerMax3']), 4)
- data += fill_2_hexByte(hex(setConf['powerMax4']), 4)
- data += fill_2_hexByte(hex(setConf['elecCheckMin']), 2)
- data += fill_2_hexByte(hex(setConf['elecCheckTime']), 2)
- data += fill_2_hexByte(hex(setConf['voice']), 2)
- if int(setConf["time1"]) < 10 or setConf["time2"] < 10 or setConf["time3"] < 10 or setConf["time4"] < 10:
- raise ServiceException({"result": 2, "description": "功率时间最小为 10 分钟"})
- result = self.send_data(SendFunCode.SET_DEV_SETTINGS, data=data)
- data = result.get("data")
- if data[6: 10] != "4F4B":
- raise ServiceException({"result": 2, "description": u"参数设置失败,请重新试试!"})
-
- def reboot_dev(self):
- """
- 重启设备
- """
- self.send_data(SendFunCode.RESET_DEV, data="0000")
- @staticmethod
- def transform_password(password):
- passwordHex = ""
- while password:
- passwordHex += fill_2_hexByte(hex(int(password[: 2])), 2)
- password = password[2:]
- return passwordHex
- def set_password(self, setConf):
- """
- 设置设备的小区密码
- 密码是否还需要再校验,以及是否是0开头
- """
- password = setConf.get("pwd")
- if len(password) != 10:
- raise ServiceException({"result": 0, "description": u"密码长度必须为10位"})
- passwordHex = self.transform_password(password)
- self.send_data(SendFunCode.SET_GROUP_PW, data=passwordHex)
-
- def set_send_card(self, setConf):
- """
- 设置卡机模式 用于重置 实体卡的小区密码
- :param setConf:
- :return:
- """
- # TODO 同上 需要设置开关
- oldPassword = setConf.get("old_pwd")
- newPassword = setConf.get("new_pwd")
- if len(oldPassword) != 10 or len(newPassword) != 10:
- raise ServiceException({"result": 0, "description": u"密码长度必须为10位"})
- oldPasswordHex = self.transform_password(oldPassword)
- newPasswordHex = self.transform_password(newPassword)
- self.send_data(SendFunCode.SET_SEND_CARD, data=oldPasswordHex+newPasswordHex)
-
- # 给实体卡充值
- def recharge_card(self, cardNo, money, orderNo=None):
- # type:(str,RMB,str)->(dict, RMB)
- """
- # TODO zjl 重点测试
- 昌原卡充值流程大致为
- 手机端卡充值成功,数据成功记录服务器
- 实体卡靠近 充值机器 然后主板发送 D4 指令 上传卡号以及卡的余额 (上抛事件)
- 服务器接受指令之后,判断是否正常卡,不是正常卡 下发同步余额为0 没有充过值 直接过滤(异步指令)
- 桩接受之后,返回同步状态 (指令模块压栈, 上抛事件)
- 服务器接受之后,返回 DF 指令(异步指令)
- 整个流程结束
- {"IMEI":"865650042848537", "cmd": 210, "data": "01090001", "funCode": "D3"}
- :param **kwargs:
- """
- # 获取充值的标志编号
- sidKey = '%s-%s' % (self._device['devNo'], cardNo)
- sid = TempValues.get(sidKey)
- # 数据域为卡内当前总金额(元) + 订单编号
- dataHex = fill_2_hexByte(hex(int(money)), 4) + fill_2_hexByte(hex(int(sid)), 4)
- MessageSender.send(device = self.device,
- cmd = DeviceCmdCode.OPERATE_DEV_NO_RESPONSE,
- payload = {
- "IMEI": self._device["devNo"],
- "funCode": SendFunCode.SYNC_CARD_BALANCE,
- "data": dataHex
- })
- def ack_event(self):
- """
- 应答报文 应答D7 D9 DA D3 指令
- :return:
- """
- MessageSender.send(device = self.device,
- cmd = DeviceCmdCode.OPERATE_DEV_NO_RESPONSE,
- payload = {
- "IMEI": self._device["devNo"],
- "funCode": SendFunCode.ANSWER_CMD,
- "data": "4F4B"
- })
- def get_port_info(self, line=None):
- devCache = Device.get_dev_control_cache(self._device["devNo"])
- return devCache.get(str(line), {})
- def set_device_function_param(self, request, lastSetConf):
- time1 = request.POST.get('time1', None)
- time2 = request.POST.get('time2', None)
- time3 = request.POST.get('time3', None)
- time4 = request.POST.get('time4', 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)
-
- elecCheckMin = request.POST.get('elecCheckMin', None)
- elecCheckTime = request.POST.get('elecCheckTime', None)
- voice = request.POST.get('voice', None)
- pw = request.POST.get("pwd", None)
- oldPw = request.POST.get("old_pwd", None)
- newPw = request.POST.get("new_pwd", None)
- discount = request.POST.get("discount")
- vCardTime = request.POST.get("vCardTime")
- maxTime = request.POST.get("maxTime")
- # 功率需要从小到大排序,这个地方要做一个校验
- if all([powerMax1, powerMax2, powerMax3, powerMax4]) and not int(powerMax1) < int(powerMax2) < int(powerMax3) < int(powerMax4):
- raise ServiceException({"result": 0, "description": u"功率参数必须从小到大设置!"})
- if time1:
- lastSetConf.update({'time1': int(time1)})
- if time2:
- lastSetConf.update({'time2': int(time2)})
- if time3:
- lastSetConf.update({'time3': int(time3)})
- if time4:
- lastSetConf.update({'time4': int(time4)})
-
- 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 elecCheckMin:
- lastSetConf.update({'elecCheckMin': int(elecCheckMin)})
- if elecCheckTime:
- lastSetConf.update({'elecCheckTime': int(elecCheckTime)})
- if voice:
- lastSetConf.update({'voice': int(voice)})
- if pw:
- lastSetConf.update({"pwd": pw})
- if oldPw:
- lastSetConf.update({"old_pwd": oldPw})
- if newPw:
- lastSetConf.update({"new_pwd": newPw})
- # 设备参数设置
- if any([time1, time2, time3, time4, powerMax1, powerMax2, powerMax3, powerMax4, elecCheckMin, elecCheckTime, voice]):
- self.set_dev_setting(lastSetConf)
- # 小区密码设置
- if pw:
- self.set_password(lastSetConf)
- # 发卡机器模式
- if all([oldPw, newPw]):
- self.set_send_card(lastSetConf)
- # 设置安全充电时长
- if maxTime is not None:
- self.set_max_time(int(maxTime))
- if discount is not None:
- otherConf = self._device.get("otherConf", dict())
- otherConf.update({"discount": str(discount)})
- Device.objects.filter(devNo=self._device["devNo"]).update(otherConf=otherConf)
- Device.invalid_device_cache(self._device["devNo"])
- if vCardTime is not None:
- otherConf = self._device.get("otherConf", dict())
- otherConf.update({"vCardTime": str(vCardTime)})
- 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 "disableButton" in request.POST:
- if "dealerDisableDevice" not in self.device.owner:
- raise ServiceException({"result": 2, "description": "抱歉,您无此操作权限,请联系厂家获取权限"})
- return self.set_dev_disable(request.POST["disableButton"])
- if "reboot" in request.POST and request.POST.get("reboot"):
- return self.reboot_dev()
-
- if "needBindCard" in request.POST:
- needBindCard = request.POST.get('needBindCard')
- otherConf = self.device.get("otherConf", dict())
- otherConf.update({"needBindCard": needBindCard})
- Device.objects.get(devNo=self.device.devNo).update(otherConf=otherConf)
- Device.invalid_device_cache(self.device.devNo)
- def set_max_time(self, maxTime):
- data = "{:04X}".format(maxTime)
- try:
- self.send_data("F8", data, timeout=5)
- except ServiceException as e:
- raise ServiceException({"result": 2, "description": u"该设备暂不支持充电时长,请联系厂家进行升级"})
- def set_dev_disable(self, disable):
- """
- 设备端锁定解锁设备
- :param disable:
- :return:
- """
- if disable:
- status = "00AA"
- else:
- status = "0055"
- result = self.send_data(funCode=SendFunCode.SET_DEV_DISABLE, data=status)
- data = result["data"]
- if data[6: 10] != "4F4B":
- raise ServiceException({'result': 2, 'description': u'设置失败,请重试吧'})
- otherConf = self._device.get("otherConf", {})
- otherConf["disableDevice"] = disable
- Device.objects.filter(devNo=self._device["devNo"]).update(otherConf=otherConf)
- Device.invalid_device_cache(self._device["devNo"])
- def handle_clear_start_error(self, port):
- dealer = Dealer.objects.get(id=self._device["ownerId"])
- if not dealer or not dealer.managerialOpenId:
- return
- group = Group.get_group(self._device["groupId"])
- notifyData = {
- "title": "设备故障报警解除",
- "device": u"{gNum}组-{lc}-{port}端口".format(gNum=self._device["groupNumber"], lc=self._device["logicalCode"], port=port),
- "location": u"{address}-{groupName}".format(address=group["address"], groupName=group["groupName"]),
- "fault": u"当前端口已被正常启动,报警解除",
- "notifyTime": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
- }
- task_caller(
- func_name='report_to_dealer_via_wechat',
- openId=dealer.managerialOpenId,
- dealerId=str(dealer.id),
- templateName="device_fault",
- **notifyData
- )
- def handle_out_start_error(self, port):
- dealer = Dealer.objects.get(id=self._device["ownerId"])
- if not dealer or not dealer.managerialOpenId:
- return
- group = Group.get_group(self._device["groupId"])
- times = Device.get_error_start_times(self._device["devNo"], port)
- notifyData = {
- "title": u"注意,您的设备可能发生故障!",
- "device": u"{gNum}组-{lc}-{port}端口".format(gNum=self._device["groupNumber"], lc=self._device["logicalCode"], port=port),
- "location": u"{address}-{groupName}".format(address=group["address"], groupName=group["groupName"]),
- "fault": u"当前设备端口连续启动 {times} 失败,请注意该端口是否发生故障".format(times=times),
- "notifyTime": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
- }
- task_caller(
- func_name='report_to_dealer_via_wechat',
- openId=dealer.managerialOpenId,
- dealerId=str(dealer.id),
- templateName="device_fault",
- **notifyData
- )
|