123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423 |
- # -*- coding: utf-8 -*-
- # !/usr/bin/env python
- import copy
- import datetime
- import time
- from apps.web.constant import DeviceCmdCode, Const, MQTT_TIMEOUT
- from apps.web.core.adapter.base import SmartBox
- from apps.web.core.exceptions import ServiceException
- from apps.web.core.networking import MessageSender
- from apps.web.device.models import Device
- from apps.web.user.models import ServiceProgress
- class AoQiangSocketNodeBox(SmartBox):
- def __init__(self, device):
- super(AoQiangSocketNodeBox, self).__init__(device)
- def translate_funcode(self, fun_code):
- fun_codeDict = {
- '01': u'查询所有子设备状态',
- '02': u'查询全部端口详情',
- '03': u'绑定设备',
- '04': u'重启设备',
- '05': u'解绑设备',
- '07': u'启动端口',
- '08': u'查询设备信息',
- '09': u'查询端口信息',
- '0B': u'设置设备配置',
- '0C': u'查询设备配置',
- }
- return fun_codeDict.get(fun_code, '')
- def translate_event_cmdcode(self, cmdCode):
- cmdDict = {
- }
- return cmdDict.get(cmdCode, '')
- def test(self, coins):
- data = {'fun_code': 0x07, 'order_id': '1111', 'chrmt': 0, 'port_id': 1, 'amount': 60}
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': self._device['devNo'], 'data': data})
- return devInfo
- def check_feedback_result(self, devInfo):
- if not devInfo.has_key('rst'):
- raise ServiceException({'result': 2, 'description': u'报文异常'})
- if devInfo['rst'] == -1:
- raise ServiceException({'result': 2, 'description': u'充电插座正在玩命找网络,请您稍候再试'})
- if devInfo['rst'] == 1:
- raise ServiceException({'result': 2, 'description': u'串口通讯失败,您稍候再试,或者联系客服'})
- if devInfo['rst'] == 2:
- raise ServiceException({'result': 2, 'description': u'设备启动超时'})
- # result = devInfo['data']['result']
- # if result == 0:
- # return
- # else:#等待设备的错误码进行细化
- # raise ServiceException({'result': 2, 'description': u'充电插座返回了错误,请您重试看看能否解决问题'})
- def get_port_from_ab(self, portAB):
- portConf = {'A': 1, 'B': 2, 'C': 3}
- if portAB in portConf:
- return portConf[portAB]
- return portAB
- def get_abport_from_index(self, port):
- portConf = {'1': 'A', '2': 'B', '3': 'C'}
- return portConf.get(port)
- def start_device(self, package, openId, attachParas):
- if attachParas is None:
- raise ServiceException({'result': 2, 'description': u'请您选择合适的充电线路、电池类型信息'})
- if not attachParas.has_key('chargeIndex'):
- raise ServiceException({'result': 2, 'description': u'请您选择合适的充电线路'})
- attachParas['chargeIndex'] = self.get_port_from_ab(attachParas['chargeIndex'])
- port = attachParas['chargeIndex']
-
- unit = package.get('unit', u'分钟')
- needTime, needElec = 0, 0
- orderNo = attachParas.get('orderNo')
- if unit == u'秒':
- if int(package['time']) < 60:
- raise ServiceException({'result': 2, 'description': u'套餐的最小时间不能小于60秒'})
- needTime = int(float(package['time'])) / 60
- data = {'fun_code': 0x07, 'chrmt': 1, 'port_id': port, 'amount': needTime}
- elif unit == u'分钟':
- needTime = int(package['time'])
- data = {'fun_code': 0x07, 'chrmt': 1, 'port_id': port, 'amount': needTime}
- elif unit == u'小时':
- needTime = int(float(package['time']) * 60)
- data = {'fun_code': 0x07, 'chrmt': 1, 'port_id': port, 'amount': needTime}
- elif unit == u'天':
- needTime = int(float(package['time']) * 60 * 24)
- data = {'fun_code': 0x07, 'chrmt': 1, 'port_id': port, 'amount': needTime}
- elif unit == u'度':
- needElec = int(float(package['time'])) * 1000
- data = {'fun_code': 0x07, 'chrmt': 2, 'port_id': port, 'amount': needElec}
- else:
- raise ServiceException({'result': 2, 'description': u'套餐配置错误'})
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': self._device['devNo'], 'data': data}, timeout=MQTT_TIMEOUT.START_DEVICE)
- self.check_feedback_result(devInfo)
- if devInfo['rst'] == 0: # 成功
- newValue = {
- 'port': str(port),
- 'status': Const.DEV_WORK_STATUS_WORKING,
- 'startTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
- 'orderNo': orderNo,
- 'coins': round(package.get('coins'), 2),
- 'isStart': True,
- 'openId': openId,
- 'chrmt': data.get('chrmt'),
- }
-
- if data.get('chrmt') == 1:
- newValue.update({'needTime': data.get('amount')})
- elif data.get('chrmt') == 2:
- newValue.update({'needElec': data.get('amount')})
-
- else: # TODO result的枚举列出原因
- raise ServiceException({'result': 2, 'description': u'充电插座响应异常,请您稍后再试哦'})
- if needTime:
- finishedTime = int(time.time()) + needTime * 60
- devInfo['needTime'] = needTime
- elif needElec:
- finishedTime = int(time.time()) + 60 * 60 * 10 # 设定10个小时,确实很难知道可以用多久结束
- devInfo['needElec'] = float(package['time'])
- else:
- finishedTime = int(time.time()) + 60 * 60 * 10 # 设定10个小时,确实很难知道可以用多久结束
- pass
- Device.update_port_control_cache(self._device['devNo'], newValue)
- devInfo.update({'finishedTime': finishedTime})
- devInfo['consumeOrderNo'] = orderNo
- return devInfo
- def analyze_event_data(self, data):
- if data['fun_code'] == '34': # 如果是结束事件,需要把reason翻译出来
- descDict = {
- '5': u'支付的金额已经使用完毕',
- '6': u'用户手工停止了充电',
- '7': u'电池充满自停',
- '8': u'故障导致充电停止',
- '9': u'本端口功率过载,主动关闭',
- '10': u'没有连接充电器,主动关闭',
- '11': u'远程关闭',
- '12': u'检测到烟雾告警,主动关闭'
- }
- order = data['order']
- order['reason'] = descDict.get(str(order['closeType']), u'')
- data['order'] = order
- return data
- def get_port_status_from_dev(self):
- # 先到设备上,把所有子节点的信息取出来,记录到主节点的缓存
- devInfo = MessageSender.send(self.device, self.make_random_cmdcode(),
- {'IMEI': self._device['devNo'], 'data': {'fun_code': 0x02}})
- self.check_feedback_result(devInfo)
- allPorts, usedPorts = 0, 0
- result = {}
- ctrInfo = Device.get_dev_control_cache(self._device.devNo)
- for portId, portInfo in devInfo['data']['ports'].items():
- portDict = {
- 'status': self.__translate_status_from_str(str(portInfo['port_status'])),
- 'power': round(portInfo['watt'], 2),
- 'leftTime': round(portInfo['left_time'], 2),
- }
- lineInfo = ctrInfo.get(portId, {})
- if lineInfo.get('status') == 1:
- if portDict['status'] == 1:
- lineInfo.update(portDict)
- if portDict['status'] == 0:
- ServiceProgress.objects.filter(**{
- 'device_imei': self.device['devNo'],
- 'port': int(portId), 'isFinished': False
- }).update(isFinished=True, expireAt = datetime.datetime.now())
- lineInfo.update(portDict)
- else:
- lineInfo['status'] = portDict['status']
- result[portId] = lineInfo
- else:
- Device.clear_port_control_cache(self._device['devNo'], portId)
- result[portId] = portDict
- allPorts += 1
- result.update({'usedPorts': usedPorts, 'allPorts': allPorts, 'usePorts': allPorts - usedPorts})
- Device.update_dev_control_cache(self._device['devNo'], result)
- return result
- def get_port_info(self, line):
- line = self.get_port_from_ab(line)
- portCache = self.get_port_status_from_dev()
- return portCache.get(str(line), {})
- def __translate_status_from_str(self, status):
- dictConf = {
- '0': Const.DEV_WORK_STATUS_IDLE,
- '1': Const.DEV_WORK_STATUS_WORKING,
- '2': Const.DEV_WORK_STATUS_FAULT,
- '3': Const.DEV_WORK_STATUS_FORBIDDEN,
- }
- return dictConf.get(status, Const.DEV_WORK_STATUS_FAULT)
- def get_port_status(self, force=False):
- if force:
- self.get_port_status_from_dev()
- portCache = Device.get_dev_control_cache(self._device['devNo'])
- result = {}
- for ii in range(5):
- if str(ii) in portCache:
- if ii == 1:
- result['A'] = portCache[str(ii)]
- elif ii == 2:
- result['B'] = portCache[str(ii)]
- elif ii == 3:
- result['C'] = portCache[str(ii)]
- return result
- def lock_unlock_port(self, port, lock=True):
- port = self.get_port_from_ab(port)
- portInfo = self.get_port_info(port)
- if portInfo['status'] == Const.DEV_WORK_STATUS_WORKING:
- raise ServiceException({'result': 2, 'description': u'当前端口正在使用,请您先关闭掉后,再操作'})
-
- if lock:
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': self._device['devNo'],
- 'data': {'fun_code': 0x60, 'port_id': port, 'action': 1}})
- else:
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': self._device['devNo'],
- 'data': {'fun_code': 0x60, 'port_id': port, 'action': 0}})
-
- self.check_feedback_result(devInfo)
- 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 stop_charging_port(self, port):
- port = self.get_port_from_ab(port)
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': self._device['devNo'], 'data': {'fun_code': 0x06, 'port_id': port}})
- self.check_feedback_result(devInfo)
- if devInfo['rst'] == 0:
- Device.update_dev_control_cache(self._device['devNo'], {str(port): {'status': Const.DEV_WORK_STATUS_IDLE}})
- return True if devInfo['rst'] == 0 else False
- def add_to_gateway(self, gatewayDevNo):
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': gatewayDevNo,
- 'data': {'fun_code': 0x03, 'sub_id': self._device['devNo']}})
- self.check_feedback_result(devInfo)
- # 子节点的父节点也要更新
- devObj = Device.objects.get(devNo=self._device['devNo'])
- devObj.gatewayNode = gatewayDevNo
- devObj.save()
- def remove_from_gateway(self, gatewayDevNo):
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': gatewayDevNo,
- 'data': {'fun_code': 0x05, 'sub_id': self._device['devNo']}})
- self.check_feedback_result(devInfo)
- # 子节点的父节点也要更新
- devObj = Device.objects.get(devNo=self._device['devNo'])
- devObj.gatewayNode = ''
- devObj.save()
- # 获取设备配置参数
- def get_dev_setting(self):
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': self._device['devNo'], 'data': {'fun_code': 0x12}})
- self.check_feedback_result(devInfo)
- configs = devInfo['data']['configs']
- modeDict = {'0': 'time', '1': 'power', '2': 'elec'}
- configs['chrmt_mode'] = modeDict.get(str(configs['chrmt_mode']))
- online_card_chrmt = str(self.device['otherConf'].get('online_card_chrmt', 1))
- configs['online_card_chrmt'] = modeDict.get(online_card_chrmt)
- configs['online_card_cost'] = self.device['otherConf'].get('online_card_cost', 10)
- configs['online_card_val'] = self.device['otherConf'].get('online_card_val', 240)
- configs['refundProtectionTime'] = self.device['otherConf'].get('refundProtectionTime', 5)
- return configs
- # 获取设备配置参数
- def set_dev_setting(self, setConf):
- configs = {'fun_code': 0x11}
- configs['mach_max_watt'] = int(setConf['mach_max_watt'])
- configs['port_max_watt'] = int(setConf['port_max_watt'])
- configs['noload_check_watt'] = int(setConf['noload_check_watt'])
- configs['noload_check_time'] = int(setConf['noload_check_time'])
- configs['float_charge_watt'] = int(setConf['float_charge_watt'])
- configs['float_charge_time'] = int(setConf['float_charge_time'])
-
- configs['power_lev_max'] = int(setConf['power_lev_max'])
- configs['power_lv1_watt'] = int(setConf['power_lv1_watt'])
- configs['power_lv1_time'] = int(setConf['power_lv1_time'])
- configs['power_lv2_watt'] = int(setConf['power_lv2_watt'])
- configs['power_lv2_time'] = int(setConf['power_lv2_time'])
- configs['power_lv3_watt'] = int(setConf['power_lv3_watt'])
- configs['power_lv3_time'] = int(setConf['power_lv3_time'])
-
-
- configs['once_card_cost'] = int(setConf['once_card_cost'])
- configs['card_lv1_val'] = int(setConf['card_lv1_val'])
- configs['card_lev_max'] = int(setConf['card_lev_max'])
- configs['card_refund_en'] = int(setConf['card_refund_en'])
- configs['coin_en'] = int(setConf['coin_en'])
- configs['volume'] = int(setConf['volume'])
- configs['temp_threshold'] = int(setConf['temp_threshold'])
- configs['close_for_full'] = int(setConf['close_for_full'])
- configs['chrmt_mode'] = {'time': 0, 'power': 1, 'elec': 2}.get(setConf['chrmt_mode'])
-
-
-
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': self._device['devNo'], 'data': configs})
-
- self.check_feedback_result(devInfo)
-
- billingType = setConf['chrmt_mode']
- online_card_chrmt = {'time': 0, 'power': 1, 'elec': 2}.get(setConf['online_card_chrmt'])
- online_card_cost = int(setConf['online_card_cost'])
- online_card_val = int(setConf['online_card_val'])
- refundProtectionTime = int(setConf.get('refundProtectionTime', 5))
- Device.get_collection().update_one({'devNo': self.device['devNo']},
- {'$set': {
- 'otherConf.billingType': billingType,
- 'otherConf.online_card_chrmt': online_card_chrmt,
- 'otherConf.online_card_cost': online_card_cost,
- 'otherConf.online_card_val': online_card_val,
- 'otherConf.refundProtectionTime': refundProtectionTime,
- }})
- Device.invalid_device_cache(self.device.devNo)
- def ack_event(self, orderNo, funCode):
- devInfo = MessageSender.send(self.device, DeviceCmdCode.PASSTHROUGH_OPERATE_DEV_NO_RESPONSE,
- {'IMEI': self._device['devNo'],
- 'data': {'fun_code': funCode, 'order_id': orderNo}})
- self.check_feedback_result(devInfo)
- def reboot_device(self):
- data = {'fun_code': 0x04}
- MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_NO_RESPONSE, {'IMEI': self._device['devNo'], 'data': data})
- def active_deactive_port(self, port, active):
- port = self.get_port_from_ab(port)
- if active:
- raise ServiceException({'result': 2, 'description': u'该设备不支持直接打开端口'})
- return self.stop_charging_port(port)
-
- def set_device_function(self,request, lastSetConf):
- print request.POST
- if request.POST.get('reboot', False) == True:
- self.reboot_device()
-
- def set_device_function_param(self, request, lastSetConf):
- newConf = copy.deepcopy(request.POST)
- lastSetConf.update(newConf)
- self.set_dev_setting(lastSetConf)
-
- def isHaveStopEvent(self):
- return True
- def stop(self, port=None):
- return self.stop_charging_port(port)
-
- def set_dev_disable(self, disable):
- """
- 设备端锁定解锁设备
- :param disable:
- :return:
- """
-
- Device.get_collection().update_one({'devNo': self._device['devNo']}, {
- '$set': {'otherConf.disableDevice': disable}})
- Device.invalid_device_cache(self.device.devNo)
|