# -*- coding: utf-8 -*- #!/usr/bin/env python import copy import datetime import time from apilib.utils_json import JsonResponse 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 ConsumeRecord class BlowerWEIFULEBox(SmartBox): def __init__(self, device): super(BlowerWEIFULEBox, self).__init__(device) def translate_funcode(self, fun_code): fun_codeDict = { '02': u'查询业务详细信息', '04': u'取消订单', '06': u'远程停止充电', '07': 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','amount':int(coins*100)} devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], 'data': data}) return devInfo def check_dev_status(self, attachParas=None): curOrder = self.get_order() if curOrder: raise ServiceException({"result": 2, "description": u"当前设备正在运行,运行完毕,才允许继续投币哦"}) 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'扫码禁用,无法使用'}) def start_device(self, package, openId, attachParas): coins = int(float(package['coins'])*100)#单位为分 onPoints = attachParas.get('onPoints') if onPoints: # 远程上分 order_no = ConsumeRecord.make_no() else: order_no = str(attachParas.get("orderNo")) data = {'fun_code':0x07,'order_id':order_no,'amount':coins} 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) data = devInfo['data'] finishedTime = int(time.time()) + 24*3600 if devInfo['rst'] == 0: # 成功 devInfo['consumeOrderNo'] = order_no newValue = { 'status': Const.DEV_WORK_STATUS_WORKING, 'startTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), 'finishedTime':finishedTime } else:#TODO result的枚举列出原因 raise ServiceException({'result': 2, 'description': u'当前设备响应异常,请您稍后再试哦'}) Device.update_dev_control_cache(self._device['devNo'], newValue) devInfo['consumeOrderNo'] = order_no devInfo['finished_time'] = finishedTime return devInfo def analyze_event_data(self, data): if data['fun_code'] == 34:#如果是结束事件,需要把reason翻译出来 descDict = { '0':u'超过时间', '1':u'使用结束', '13':u'用户关闭结束', '14':u'管理员远程结束' } order = data['order'] order['reason'] = descDict.get(str(order['cause']),u'') data['order'] = order return data def __translate_status_from_str(self,status): dictConf = { 'idle':Const.DEV_WORK_STATUS_IDLE, 'busy':Const.DEV_WORK_STATUS_WORKING, 'forbid':Const.DEV_WORK_STATUS_FORBIDDEN, 'fault':Const.DEV_WORK_STATUS_FAULT, 'running':Const.DEV_WORK_STATUS_WORKING } return dictConf.get(status,Const.DEV_WORK_STATUS_IDLE) #停止该端口下的所有任务 def stop_charging_port(self, port=None): devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], 'data': {'fun_code': 0x06}}) self.check_feedback_result(devInfo) if devInfo['rst'] == 0: Device.update_dev_control_cache(self._device['devNo'], {'status': Const.DEV_WORK_STATUS_IDLE}) return True if devInfo['rst'] == 0 else False def get_order(self,order_no=None): devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,{'IMEI': self._device['devNo'], 'data': {'fun_code': 0x02, 'exec_orders': True}}) self.check_feedback_result(devInfo) orders = devInfo['data'].get('exec_orders',None) if not orders: return None curOrder = orders[0] result = {} if not curOrder or not curOrder.has_key('order_type'):#有可能没有订单,应该返回空 return result result['status'] = curOrder['status'] if curOrder['order_type'] == 'apps_start': result['consumeType'] = 'mobile' try: rcd = ConsumeRecord.objects.get(orderNo = curOrder['id']) if u'虚拟卡' in rcd.remarks: result['consumeType'] = 'mobile_vcard' except Exception,e: pass elif curOrder['order_type'] == 'coin_start': result['consumeType'] = 'coin' elif curOrder['order_type'] == 'card_start': result['consumeType'] = 'card' if curOrder.has_key('total_time'): result['needTime'] = round(curOrder['total_time']/60.0,1) if curOrder.has_key('time'): result['duration'] = round(curOrder['time']/60.0,1) result['usedTime'] = round(curOrder['time']/60.0,1) if curOrder.has_key('left_time'): result['leftTime'] = round(curOrder['left_time']/60.0,1) if curOrder.has_key('exec_time'): result['startTime'] = datetime.datetime.fromtimestamp(int(curOrder['exec_time'])).strftime('%m-%d %H:%M:%S') if curOrder.has_key('card_no'): result['cardNo'] = str(int(curOrder['card_no'],16)) if curOrder.has_key('id') and (curOrder['order_type'] not in ['coin_start','card_charge']) :#card_charge try: rcd = ConsumeRecord.objects.get(orderNo = curOrder['id']) result['openId'] = rcd['openId'] result['coins'] = float(str(rcd['coin']))#都用coins result['money'] = float(str(rcd['money'])) result['orderNo'] = str(curOrder['id']) except Exception,e: pass return result def response_card_balance(self, cardNo,balance,result): devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], 'data': {'fun_code':35,'card_no':cardNo,'balance':int(100*float(balance)),'result':result}}) self.check_feedback_result(devInfo) # 获取设备配置参数 def get_dev_setting(self): devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], 'data': {'fun_code': 0x0C}}) self.check_feedback_result(devInfo) result = devInfo['data'] result.pop('fun_code') return result # 获取设备配置参数 def set_dev_setting(self, setConf): data = {'fun_code':0x0B} data.update(setConf) if not (int(setConf['volume']) >= 0 and int(setConf['volume']) <= 7): raise ServiceException({'result': 2, 'description': u'音量必须大于等于0,小于等于7'}) devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], 'data': data}) self.check_feedback_result(devInfo) 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 set_device_function_param(self, request, lastSetConf): newConf = copy.deepcopy(request.POST) newConf.pop('logicalCode', None) self.set_dev_setting(newConf) def translante_card_no(self,hexCardNo): return int(hexCardNo,16) def set_device_function(self, request, lastSetConf): if request.POST.has_key('stop') and request.POST.get('stop'): self.stop_charging_port() lastSetConf.update(request.POST) lastSetConf.pop('logicalCode', None) self.set_dev_setting(lastSetConf) def support_count_down(self,openId=None,port=None): return True def count_down(self, request, dev, agent, group, devType, lastOpenId, port = None): curOrder = self.get_order() status = 'idle' if curOrder: status = 'working' surplus = curOrder['leftTime'] sumtime = curOrder.get('needTime', surplus) orderProcessing = False if surplus == 0.0 and sumtime == 0.0: orderProcessing = True return JsonResponse( { 'result': 1, 'description': '', 'payload': { 'workStatus': status, 'surplus': surplus, 'sum': sumtime, 'name': group['groupName'], 'address': group['address'], 'code': devType.get('code'), 'orderProcessing': orderProcessing, 'logicalCode': dev['logicalCode'], 'user': 'me' if lastOpenId == request.user.openId else 'notme', 'agentFeatures': agent.features, } }) def stop(self, port = None): return self.stop_charging_port() def isHaveStopEvent(self): return True