# -*- coding: utf-8 -*- # !/usr/bin/env python import datetime import logging import time from apilib.utils_datetime import to_datetime, timestamp_to_dt from apps.web.constant import Const, MQTT_TIMEOUT, DeviceCmdCode from apps.web.core.adapter.base import MqttSmartBox, fill_2_hexByte from apps.web.core.exceptions import ServiceException from apps.web.core.networking import MessageSender from apps.web.device.models import Device logger = logging.getLogger(__name__) class HeshuiChongdian(MqttSmartBox): def __init__(self, device): super(HeshuiChongdian, self).__init__(device) def analyze_event_data(self, data): if 'FB' == data[0:2]: return {'cmdCode': 'FB', 'port': 3} elif 'FD' in data[0:2]: if len(data) > 2: leftTime = int(data[2:6], 16) else: leftTime = -1 return {'cmdCode': 'FD', 'port': 3, 'leftTime': leftTime} elif '01' in data[0:2]: return {'cmdCode': '01', 'usedTime': int(data[2:4], 16), 'port': 1} elif '02' in data[0:2]: return {'cmdCode': '02', 'usedTime': int(data[2:4], 16), 'port': 2} return None def get_port_info(self, line): if str(line) in ['1', '2']: ctrInfo = Device.get_dev_control_cache(self._device['devNo']) if ctrInfo is None or (not ctrInfo.has_key(str(line))): return {'port': line, 'leftTime': 0} portInfo = ctrInfo.get(str(line)) if portInfo.has_key('startTime') and portInfo.has_key('needTime'): startTime = to_datetime(portInfo['startTime']) needTime = portInfo['needTime'] leftTime = round((needTime - (datetime.datetime.now() - startTime).total_seconds()) / 60.0, 2) if leftTime <= 0: return {'port': line, 'leftTime': 0} return {'port': line, 'leftTime': leftTime} else: return {'port': line, 'leftTime': 0} leftTime = self.get_left_time_from_chargePort() return {'port': line, 'leftTime': leftTime} def get_port_status_from_dev(self): ctrInfo = Device.get_dev_control_cache(self._device['devNo']) device = Device.objects(devNo = self._device['devNo']).first() if device.otherConf.get('isMainboardDetection', False) is True: devInfo = MessageSender.send(self.device, 210, {'IMEI': self._device['devNo'], 'serialType': 'charger', 'funCode': 'FC', 'data': ''}) if devInfo.has_key('rst') and devInfo['rst'] != 0: if devInfo['rst'] == -1: raise ServiceException({'result': 2, 'description': u'设备正在玩命找网络,建议您试试旁边其他设备,或者稍后再试哦'}) elif devInfo['rst'] == 1: raise ServiceException({'result': 2, 'description': u'设备忙,无响应,请您稍候再试。建议您试试旁边其他设备,或者稍后再试哦'}) if devInfo['data'] != '0000': ctrInfo.update({'1': {'status': Const.DEV_WORK_STATUS_WORKING}}) else: ctrInfo.update({'1': {'status': Const.DEV_WORK_STATUS_IDLE}}) else: ctrInfo.update({'1': {'status': Const.DEV_WORK_STATUS_IDLE}}) Device.update_dev_control_cache(self._device['devNo'], ctrInfo) def get_port_status(self, force = False): if force: return self.get_port_status_from_dev() portDict = {} ctrInfo = Device.get_dev_control_cache(self._device['devNo']) if ctrInfo.has_key('1') and ctrInfo['1'].has_key('startTime') and ctrInfo['1'].has_key('needTime'): portDict.update({'1': {'status': Const.DEV_WORK_STATUS_WORKING}}) startTime = to_datetime(ctrInfo['1'].get('startTime')) if (datetime.datetime.now() - startTime).total_seconds() >= 60: portDict.update({'1': {'status': Const.DEV_WORK_STATUS_IDLE}}) else: portDict.update({'1': {'status': Const.DEV_WORK_STATUS_WORKING}}) else: portDict.update({'1': {'status': Const.DEV_WORK_STATUS_IDLE}}) if ctrInfo.has_key('2') and ctrInfo['2'].has_key('startTime') and ctrInfo['2'].has_key('needTime'): portDict.update({'2': {'status': Const.DEV_WORK_STATUS_WORKING}}) startTime = to_datetime(ctrInfo['2'].get('startTime')) if (datetime.datetime.now() - startTime).total_seconds() >= 60: portDict.update({'2': {'status': Const.DEV_WORK_STATUS_IDLE}}) else: portDict.update({'2': {'status': Const.DEV_WORK_STATUS_WORKING}}) else: portDict.update({'2': {'status': Const.DEV_WORK_STATUS_IDLE}}) return portDict def start_device(self, package, openId, attachParas): #: 首先检查设备是否在线 unit = package.get('unit', u'分钟') coins = package.get('price') port = int(attachParas.get('chargeIndex')) if unit == u'分钟': # 如果单位为分钟,就认为是充电 needTimeInput = int(package['time']) needTime = needTimeInput * 60 serialType = 'charger' funCode = '0A' data = fill_2_hexByte(hex(needTimeInput), 4) elif unit == u'秒': # 如果单位是秒,就认为是接水 needTime = int(package['time']) serialType = 'water' if port == 1: funCode = '01' else: funCode = '02' data = '' else: raise ServiceException({'result': 2, 'description': u'套餐单位错误,无法启动哦'}) devInfo = MessageSender.send(device = self.device, cmd = 220, payload = { 'IMEI': self._device['devNo'], 'serialType': serialType, "funCode": funCode, 'data': data }, timeout = MQTT_TIMEOUT.START_DEVICE) if devInfo.has_key('rst') and devInfo['rst'] != 0: if devInfo['rst'] == -1: raise ServiceException({'result': 2, 'description': u'设备正在玩命找网络,您的金币还在,重试不需要重新付款,建议您试试旁边其他设备,或者稍后再试哦'}) elif devInfo['rst'] == 1: raise ServiceException({'result': 2, 'description': u'设备正在忙,无响应,您的金币还在,重试不需要重新付款,请试试其他线路,或者请稍后再试哦'}) start_timestamp = int(time.time()) if serialType == 'charger': devInfo['finishedTime'] = (int(time.time()) + int(needTime)) else: devInfo['finishedTime'] = (int(time.time()) + 60) value = { 'openId': openId, 'startTime': timestamp_to_dt(start_timestamp).strftime('%Y-%m-%d %H:%M:%S'), 'serialType': serialType, 'needTime': needTime, 'coins': coins, 'vCardId': self._vcard_id, 'status': Const.DEV_WORK_STATUS_WORKING, 'finishedTime': devInfo['finishedTime'] } if 'linkedRechargeRecordId' in attachParas and attachParas.get('isQuickPay', False): item = { 'rechargeRcdId': str(attachParas['linkedRechargeRecordId']) } value['payInfo'] = [item] logger.info('port value is %s' % value) Device.update_dev_control_cache(self._device['devNo'], {str(port): value}) return devInfo def get_left_time_from_chargePort(self): devInfo = MessageSender.send(self.device, 210, {'IMEI': self._device['devNo'], 'funCode': 'FC', 'data': ''}) if devInfo.has_key('rst') and devInfo['rst'] != 0: raise ServiceException({'result': 2, 'description': u'当前设备正在玩命找网络,建议您试试旁边其他设备,或者试试投硬币,或者稍后再试哦'}) leftTime = int(devInfo['data'], 16) return leftTime def set_standard_pulse(self, standardPulse): standardPulse = fill_2_hexByte(hex(int(standardPulse))) MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], "funCode": '6b', 'data': standardPulse}) def set_standard_count_and_time(self, standardCount, standardTime): standardCount = fill_2_hexByte(hex(int(standardCount)), num = 2) standardTime = fill_2_hexByte(hex(int(standardTime)), num = 2) MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], "funCode": 'f5', 'data': standardCount + standardTime}) def set_unit_pulse_detection(self): MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], "funCode": 'b7', 'data': 'caca'}) def set_device_function_param(self, request, lastSetConf): if 'standardPulse' in request.POST: standardPulse = request.POST['standardPulse'] if standardPulse != '': self.set_standard_pulse(standardPulse) if 'standardCount' in request.POST and 'standardTime' in request.POST: standardCount = request.POST['standardCount'] standardTime = request.POST['standardTime'] if standardCount != '' and standardTime != '': self.set_standard_count_and_time(standardCount, standardTime) def get_dev_setting(self): device = Device.objects(devNo = self._device['devNo']).first() return {'isMainboardDetection': device.otherConf.get('isMainboardDetection', False)} def set_device_function(self, request, lastSetConf): if 'unitPulseDetection' in request.POST: self.set_unit_pulse_detection() if 'isMainboardDetection' in request.POST: isMainboardDetection = request.POST['isMainboardDetection'] device = Device.objects(devNo = self._device['devNo']).first() device.otherConf['isMainboardDetection'] = isMainboardDetection device.save()