def check_upgrade_fw(device, cmdobj): ''' 固件升级相关 ''' if cmdobj.CmdContent.find("PutFile file/fw/") == 0 and cmdobj.CmdContent.find("main.") > 0: #it is an upgrade firmware command if hasattr(device, "is_updating_fw"): del device.is_updating_fw url, fname = getFW(device) q_server=check_and_start_queqe_server() q_server.decr("UPGRADE_FW_COUNT") diff = int(cmdobj.CmdReturn)-os.path.getsize(fname) #返回的文件字节数和实际的文件字节数比较 if diff in [0, 1]: #升级成功, 有一旧版本的固件下载文件后会多出一个字节 fname=os.path.split(fname)[1] if cmdobj.CmdContent.find("%s.tmp"%fname) > 0: #如果是下载固件到临时文件的话需要改名 append_dev_cmd(device, "Shell mv %s.tmp /mnt/mtdblock/%s"%(fname, fname)) append_dev_cmd(device, "REBOOT") #重新启动机器 else: append_dev_cmd(device, cmdobj.CmdContent) #重新失败,重新发送升级命令 q_server.connection.disconnect()
def check_upgrade_fw(device, cmdobj): ''' 固件升级相关 ''' if cmdobj.CmdContent.find( "PutFile file/fw/") == 0 and cmdobj.CmdContent.find( "main.") > 0: #it is an upgrade firmware command if hasattr(device, "is_updating_fw"): del device.is_updating_fw url, fname = getFW(device) q_server = check_and_start_queqe_server() q_server.decr("UPGRADE_FW_COUNT") diff = int(cmdobj.CmdReturn) - os.path.getsize( fname) #返回的文件字节数和实际的文件字节数比较 if diff in [0, 1]: #升级成功, 有一旧版本的固件下载文件后会多出一个字节 fname = os.path.split(fname)[1] if cmdobj.CmdContent.find( "%s.tmp" % fname) > 0: #如果是下载固件到临时文件的话需要改名 append_dev_cmd( device, "Shell mv %s.tmp /mnt/mtdblock/%s" % (fname, fname)) append_dev_cmd(device, "REBOOT") #重新启动机器 else: append_dev_cmd(device, cmdobj.CmdContent) #重新失败,重新发送升级命令 q_server.connection.disconnect()
def get_redis_rtlog(request): logid = int(request.GET.get('logid', FIRSTVISIT_OR_DELBACKEND)) step = int(request.GET.get('step', 0)) #步长:即要log的最大条数 rt_type = request.GET.get('type', '') #all alarm devid = request.REQUEST.get("devid", 0) #默认为0,表示监控所有设备的所有门的状态 #再获取实时监控记录 q_server = check_and_start_queqe_server() #print "--",logid+step # cfg = dict4ini.DictIni(os.getcwd()+"/appconfig.ini",values={"iaccess": {"down_newlog": 0}}) #默认0点定时下载新记录,定时删除缓存 # now_hour = datetime.datetime.now().hour # if now_hour == cfg.iaccess.down_newlog: # q_server.delete("MONITOR_RT") # q_server.delete("ALARM_RT") # logid = -1#重新取 rtid_all = 0 #缓存里所有的记录条数 rtid_alarm = 0 #缓存里所有的报警事件记录 log_count = 0 #返回的有效记录条数 valid_devices = [] if rt_type == "all": rtid_all = q_server.lock_rlen( "MONITOR_RT") #被锁住时以及文件缓存为空时都返回-1,即该值不可能为0 此时前端继续使用原来的logid取数据 if (rtid_all != LOCKED_OR_NOTHING) and ( rtid_all < logid): #主要用于后台服务0时定时删除监控缓存时可能导致的不一致,故重新取,当数据量少时未必准确。 logid = FIRSTVISIT_OR_DELBACKEND #重新取 #获取门状态door_states valid_devices = obtain_valid_devices(request) #print '---valid_devices=',valid_devices door_states = door_state_monitor(valid_devices) #门状态不涉及辅助输入点,故不需调整 if logid == FIRSTVISIT_OR_DELBACKEND: #监控全部时获取报警记录的初始id值 rtid_alarm = q_server.llen("ALARM_RT") rtlog = q_server.lrange("MONITOR_RT", logid, logid + step) elif rt_type == "alarm": rtid_alarm = q_server.lock_rlen("ALARM_RT") if (rtid_alarm != LOCKED_OR_NOTHING) and ( rtid_alarm < logid ): #主要用于后台服务0时定时删除监控缓存时可能导致的不一致,故重新取,当数据量少时未必准确。--包含发现报警事件的按钮如果被删除,那么跳转后直接重新开始 logid = FIRSTVISIT_OR_DELBACKEND #重新取 door_states = {"data": []} rtlog = q_server.lrange("ALARM_RT", logid, logid + step) #rtlog数据格式如下“0-时间 + 1-PIN号 + 2-门id + 3-事件类型 + 4-出入状态 +5-验证方式 +6-卡号+7-设备号” #rtlog = ['2010-03-07 09:53:51,370,4,6,0,221,36656656'] #print 'door_states=',door_states #print "----------------------rtlog=", rtlog q_server.connection.disconnect() cdatas = [] a_logids = [] #如下代码测试时请注释掉 if logid == FIRSTVISIT_OR_DELBACKEND: cc = { 'log_id': logid, 'all_id': (rtid_all != LOCKED_OR_NOTHING) and rtid_all or 0, #redis中所有记录条数 'alarm_id': rtid_alarm, 'log_count': log_count, #返回的记录条数 'data': cdatas, 'door_states': door_states["data"], } rtdata = simplejson.dumps(cc) return HttpResponse(smart_str(rtdata)) if not valid_devices: #如果之前没有进入“all”则需要重新获取有效设备(主要是避免重新获取,每次请求只获取一次即可) valid_devices = obtain_valid_devices(request) #通过设备找到对应的门以及辅助输入,作为事件点 for alog in rtlog: log = alog.strip() #print "log=", log #验证数据合法性,保证了除了时间之外的数据都是数字字符,从而可以使用int()而不会出错 p1 = re.compile( r'(((^((1[8-9]\d{2})|([2-9]\d{3}))([-\/\._])(10|12|0?[13578])([-\/\._])(3[01]|[12][0-9]|0?[1-9]))|(^((1[8-9]\d{2})|([2-9]\d{3}))([-\/\._])(11|0?[469])([-\/\._])(30|[12][0-9]|0?[1-9]))|(^((1[8-9]\d{2})|([2-9]\d{3}))([-\/\._])(0?2)([-\/\._])(2[0-8]|1[0-9]|0?[1-9]))|(^([2468][048]00)([-\/\._])(0?2)([-\/\._])(29))|(^([3579][26]00)([-\/\._])(0?2)([-\/\._])(29))|(^([1][89][0][48])([-\/\._])(0?2)([-\/\._])(29))|(^([2-9][0-9][0][48])([-\/\._])(0?2)([-\/\._])(29))|(^([1][89][2468][048])([-\/\._])(0?2)([-\/\._])(29))|(^([2-9][0-9][2468][048])([-\/\._])(0?2)([-\/\._])(29))|(^([1][89][13579][26])([-\/\._])(0?2)([-\/\._])(29))|(^([2-9][0-9][13579][26])([-\/\._])(0?2)([-\/\._])(29)))((\s+(0?[1-9]|1[012])(:[0-5]\d){0,2}(\s[AP]M))?$|(\s+([01]\d|2[0-3])(:[0-5]\d){0,2})?$))' ) p2 = re.compile(r'^,(((\d+),){6}\d+)$') #r'^,(((\d+),){4}\d+)?$' 5-6 if p1.match(log[0:19]) and p2.match(log[19:]): log_count += 1 str = log.split(",", 8) #0-7 共8部分 #print "accmonitorlog=", str #设备名称 dev_id = int(str[7]) dev = Device.objects.filter(pk=dev_id) alias = dev and unicode(dev[0].alias) or "" if dev and dev[ 0] not in valid_devices: #设备级别的过滤--辅助输入(含联动中触发条件为辅助输入点的) break #事件类型 event = int(str[3]) #验证方式(或源事件类型),但是当事件为联动事件时为联动事件的原事件 veri_event = int(str[5]) #卡号-联动时复用为联动id号(pk) card_no = int(str[6]) and str[6] or '' door_id = 0 link_video = [] #print '---vari_event=',veri_event,' event=',event,' door_id',door_id, if event == 220 or event == 221: #辅助输入点的事件 #事件点 in_address_id = int(str[2]) #辅助输入点,如1,2,3,4 9,10,11,12 event_point = unicode(dict(IN_ADDRESS_CHOICES)[in_address_id]) #验证方式 try: verified = unicode( dict(VERIFIED_CHOICES)[veri_event] ) #the true verified method("others" included) except: verified = unicode(_(u"数据异常")) else: #与门相关 door_id_limit = obtain_valid_doors( request, valid_devices) #可控的ip地址,不包含辅助输入点 if event == 6: #事件类型为联动事件 #print '----------------event=',event #verified = ''#联动事件验证方式为空-固件字段复用--触发的原事件 verified = unicode(dict(VERIFIED_CHOICES)[200]) #其他 if veri_event == 220 or veri_event == 221: number = int(str[2]) #如C4 9,10,11,12 event_point = unicode(dict(IN_ADDRESS_CHOICES)[number]) #linkage = AccLinkageIO.objects.filter(Q(device__id=dev_id), Q(trigger_opt=veri_event), Q(in_address_hide=number)|Q(in_address_hide=0))#输入点inout或0只能居其一 else: door_id = int(str[2]) #门id(不同于门编号) if door_id not in door_id_limit: #门级别的过滤 break #跳出for循环,该记录无效 #事件点 doors = AccDoor.objects.filter(id=door_id) event_point = doors and unicode(doors[0]) or "" #视频联动处理 try: link_id = int(card_no) or 0 #联动时卡号复用为联动id号 except: link_id = 1 card_no = '' #联动时不需要显示卡号 #print "link_id=", link_id from mysite.iaccess.models import AccLinkageIO try: linkage = AccLinkageIO.objects.filter(id=link_id) if linkage: pwd = linkage[0].video_linkageio.comm_pwd link_video.append( linkage[0].video_linkageio.ipaddress) link_video.append( linkage[0].video_linkageio.ip_port) link_video.append( linkage[0].video_linkageio.video_login) link_video.append(pwd and decrypt(pwd) or "") link_video.append(linkage[0].lchannel_num) except: print_exc() else: #其他事件--门相关或设备相关 door_id = int(str[2]) #门id--如果为0,指的是事件点为设备(如取消报警事件) if door_id: #不为0 if door_id not in door_id_limit: #门级别的过滤 break #跳出for循环,该记录无效 #事件点 doors = AccDoor.objects.filter(id=door_id) event_point = doors and unicode(doors[0]) or "" else: event_point = "" #如取消报警事件 try: verified = unicode( dict(VERIFIED_CHOICES)[veri_event] ) #the true verified method("others" included) except: verified = unicode(_(u"数据异常")) try: event_content = unicode(dict( EVENT_CHOICES)[event]) #description of the triggered event except: event_content = unicode(_(u"数据异常")) #print 'str[1]=',str[1] pin_str = int(str[1]) and unicode(format_pin(str[1])) or '' #print '---pin_str=',pin_str emps = pin_str and Employee.objects.filter(PIN=pin_str) or '' #print 'emps=',emps if emps: empname = emps[0].EName and u"%s(%s)" % ( str[1], emps[0].EName) or u"%s" % (str[1]) photo = emps[0].photo and '/file/' + unicode( emps[0].photo) or '' else: empname = '' photo = '' #print '--str[6]=',str[6] #state = int(str[4])!=2 and unicode(dict(STATE_CHOICES)[int(str[4])]) or ''#2直接显示空 #连动视频 #print "link_video=", link_video #print '---photo=',photo cdata = { 'time': str[0], 'card': card_no, #'door': doorname,#输入点,包含门名称或者辅助输入点 'device': alias, #设备名称 'event_point': event_point, #输入点,包含门名称或者辅助输入点 'door_id': door_id, #doorid 'event_type': int(str[3]), 'content': event_content, 'state': unicode(dict(STATE_CHOICES)[int(str[4])]), #0出,1入 'verified': verified, 'emp': empname, #用户名(包含用户编号) 'photo': photo, #有人员照片的要显示,如/file/photo/000000121.jpg 空代表无照片(或无此人) 'link_video': link_video, } cdatas.append(cdata) else: print "DATA ERROR" cc = { 'log_id': logid, 'all_id': rtid_all, #无效 'alarm_id': rtid_alarm, 'log_count': log_count, #返回的有效的记录条数,用于改变logid 'data': cdatas, 'door_states': door_states["data"], #门状态数据 } #print "**########**cc=",cc rtdata = simplejson.dumps(cc) return HttpResponse(smart_str(rtdata))
def get_redis_rtlog(request): logid = int(request.GET.get('logid', FIRSTVISIT_OR_DELBACKEND)) step = int(request.GET.get('step', 0))#步长:即要log的最大条数 rt_type = request.GET.get('type', '')#all alarm devid = request.REQUEST.get("devid", 0)#默认为0,表示监控所有设备的所有门的状态 #再获取实时监控记录 q_server = check_and_start_queqe_server() #print "--",logid+step # cfg = dict4ini.DictIni(os.getcwd()+"/appconfig.ini",values={"iaccess": {"down_newlog": 0}}) #默认0点定时下载新记录,定时删除缓存 # now_hour = datetime.datetime.now().hour # if now_hour == cfg.iaccess.down_newlog: # q_server.delete("MONITOR_RT") # q_server.delete("ALARM_RT") # logid = -1#重新取 rtid_all = 0#缓存里所有的记录条数 rtid_alarm = 0#缓存里所有的报警事件记录 log_count = 0#返回的有效记录条数 valid_devices = [] if rt_type == "all": rtid_all = q_server.lock_rlen("MONITOR_RT")#被锁住时以及文件缓存为空时都返回-1,即该值不可能为0 此时前端继续使用原来的logid取数据 if (rtid_all != LOCKED_OR_NOTHING) and (rtid_all < logid):#主要用于后台服务0时定时删除监控缓存时可能导致的不一致,故重新取,当数据量少时未必准确。 logid = FIRSTVISIT_OR_DELBACKEND#重新取 #获取门状态door_states valid_devices = obtain_valid_devices(request) #print '---valid_devices=',valid_devices door_states = door_state_monitor(valid_devices)#门状态不涉及辅助输入点,故不需调整 if logid == FIRSTVISIT_OR_DELBACKEND:#监控全部时获取报警记录的初始id值 rtid_alarm = q_server.llen("ALARM_RT") rtlog = q_server.lrange("MONITOR_RT", logid, logid + step) elif rt_type == "alarm": rtid_alarm = q_server.lock_rlen("ALARM_RT") if (rtid_alarm != LOCKED_OR_NOTHING) and (rtid_alarm < logid):#主要用于后台服务0时定时删除监控缓存时可能导致的不一致,故重新取,当数据量少时未必准确。--包含发现报警事件的按钮如果被删除,那么跳转后直接重新开始 logid = FIRSTVISIT_OR_DELBACKEND#重新取 door_states = { "data": []} rtlog = q_server.lrange("ALARM_RT", logid, logid + step) #rtlog数据格式如下“0-时间 + 1-PIN号 + 2-门id + 3-事件类型 + 4-出入状态 +5-验证方式 +6-卡号+7-设备号” #rtlog = ['2010-03-07 09:53:51,370,4,6,0,221,36656656'] #print 'door_states=',door_states #print "----------------------rtlog=", rtlog q_server.connection.disconnect() cdatas = [] a_logids = [] #如下代码测试时请注释掉 if logid == FIRSTVISIT_OR_DELBACKEND: cc={ 'log_id': logid, 'all_id': (rtid_all != LOCKED_OR_NOTHING) and rtid_all or 0,#redis中所有记录条数 'alarm_id': rtid_alarm, 'log_count': log_count,#返回的记录条数 'data': cdatas, 'door_states': door_states["data"], } rtdata = simplejson.dumps(cc) return HttpResponse(smart_str(rtdata)) if not valid_devices:#如果之前没有进入“all”则需要重新获取有效设备(主要是避免重新获取,每次请求只获取一次即可) valid_devices = obtain_valid_devices(request)#通过设备找到对应的门以及辅助输入,作为事件点 for alog in rtlog: log = alog.strip() #print "log=", log #验证数据合法性,保证了除了时间之外的数据都是数字字符,从而可以使用int()而不会出错 p1 = re.compile(r'(((^((1[8-9]\d{2})|([2-9]\d{3}))([-\/\._])(10|12|0?[13578])([-\/\._])(3[01]|[12][0-9]|0?[1-9]))|(^((1[8-9]\d{2})|([2-9]\d{3}))([-\/\._])(11|0?[469])([-\/\._])(30|[12][0-9]|0?[1-9]))|(^((1[8-9]\d{2})|([2-9]\d{3}))([-\/\._])(0?2)([-\/\._])(2[0-8]|1[0-9]|0?[1-9]))|(^([2468][048]00)([-\/\._])(0?2)([-\/\._])(29))|(^([3579][26]00)([-\/\._])(0?2)([-\/\._])(29))|(^([1][89][0][48])([-\/\._])(0?2)([-\/\._])(29))|(^([2-9][0-9][0][48])([-\/\._])(0?2)([-\/\._])(29))|(^([1][89][2468][048])([-\/\._])(0?2)([-\/\._])(29))|(^([2-9][0-9][2468][048])([-\/\._])(0?2)([-\/\._])(29))|(^([1][89][13579][26])([-\/\._])(0?2)([-\/\._])(29))|(^([2-9][0-9][13579][26])([-\/\._])(0?2)([-\/\._])(29)))((\s+(0?[1-9]|1[012])(:[0-5]\d){0,2}(\s[AP]M))?$|(\s+([01]\d|2[0-3])(:[0-5]\d){0,2})?$))') p2 = re.compile(r'^,(((\d+),){6}\d+)$')#r'^,(((\d+),){4}\d+)?$' 5-6 if p1.match(log[0:19]) and p2.match(log[19:]): log_count += 1 str = log.split(",",8)#0-7 共8部分 #print "accmonitorlog=", str #设备名称 dev_id = int(str[7]) dev = Device.objects.filter(pk=dev_id) alias = dev and unicode(dev[0].alias) or "" if dev and dev[0] not in valid_devices:#设备级别的过滤--辅助输入(含联动中触发条件为辅助输入点的) break #事件类型 event = int(str[3]) #验证方式(或源事件类型),但是当事件为联动事件时为联动事件的原事件 veri_event = int(str[5]) #卡号-联动时复用为联动id号(pk) card_no = int(str[6]) and str[6] or '' door_id = 0 link_video = [] #print '---vari_event=',veri_event,' event=',event,' door_id',door_id, if event == 220 or event == 221:#辅助输入点的事件 #事件点 in_address_id = int(str[2])#辅助输入点,如1,2,3,4 9,10,11,12 event_point = unicode(dict(IN_ADDRESS_CHOICES)[in_address_id]) #验证方式 try: verified = unicode(dict(VERIFIED_CHOICES)[veri_event])#the true verified method("others" included) except: verified = unicode(_(u"数据异常")) else:#与门相关 door_id_limit = obtain_valid_doors(request, valid_devices)#可控的ip地址,不包含辅助输入点 if event == 6:#事件类型为联动事件 #print '----------------event=',event #verified = ''#联动事件验证方式为空-固件字段复用--触发的原事件 verified = unicode(dict(VERIFIED_CHOICES)[200])#其他 if veri_event == 220 or veri_event == 221: number = int(str[2]) #如C4 9,10,11,12 event_point = unicode(dict(IN_ADDRESS_CHOICES)[number]) #linkage = AccLinkageIO.objects.filter(Q(device__id=dev_id), Q(trigger_opt=veri_event), Q(in_address_hide=number)|Q(in_address_hide=0))#输入点inout或0只能居其一 else: door_id = int(str[2])#门id(不同于门编号) if door_id not in door_id_limit:#门级别的过滤 break #跳出for循环,该记录无效 #事件点 doors = AccDoor.objects.filter(id=door_id) event_point = doors and unicode(doors[0]) or "" #视频联动处理 try: link_id = int(card_no) or 0#联动时卡号复用为联动id号 except: link_id = 1 card_no = ''#联动时不需要显示卡号 #print "link_id=", link_id from mysite.iaccess.models import AccLinkageIO try: linkage = AccLinkageIO.objects.filter(id = link_id) if linkage: pwd = linkage[0].video_linkageio.comm_pwd link_video.append(linkage[0].video_linkageio.ipaddress) link_video.append(linkage[0].video_linkageio.ip_port) link_video.append(linkage[0].video_linkageio.video_login) link_video.append(pwd and decrypt(pwd) or "") link_video.append(linkage[0].lchannel_num) except: print_exc() else:#其他事件--门相关或设备相关 door_id = int(str[2])#门id--如果为0,指的是事件点为设备(如取消报警事件) if door_id:#不为0 if door_id not in door_id_limit:#门级别的过滤 break #跳出for循环,该记录无效 #事件点 doors = AccDoor.objects.filter(id=door_id) event_point = doors and unicode(doors[0]) or "" else: event_point = ""#如取消报警事件 try: verified = unicode(dict(VERIFIED_CHOICES)[veri_event])#the true verified method("others" included) except: verified = unicode(_(u"数据异常")) try: event_content = unicode(dict(EVENT_CHOICES)[event])#description of the triggered event except: event_content = unicode(_(u"数据异常")) #print 'str[1]=',str[1] pin_str = int(str[1]) and unicode(format_pin(str[1])) or '' #print '---pin_str=',pin_str emps = pin_str and Employee.objects.filter(PIN = pin_str) or '' #print 'emps=',emps if emps: empname = emps[0].EName and u"%s(%s)"%(str[1], emps[0].EName) or u"%s"%(str[1]) photo = emps[0].photo and '/file/' + unicode(emps[0].photo) or '' else: empname = '' photo = '' #print '--str[6]=',str[6] #state = int(str[4])!=2 and unicode(dict(STATE_CHOICES)[int(str[4])]) or ''#2直接显示空 #连动视频 #print "link_video=", link_video #print '---photo=',photo cdata={ 'time': str[0], 'card': card_no, #'door': doorname,#输入点,包含门名称或者辅助输入点 'device': alias,#设备名称 'event_point': event_point,#输入点,包含门名称或者辅助输入点 'door_id': door_id,#doorid 'event_type': int(str[3]), 'content': event_content, 'state': unicode(dict(STATE_CHOICES)[int(str[4])]),#0出,1入 'verified': verified, 'emp': empname,#用户名(包含用户编号) 'photo': photo,#有人员照片的要显示,如/file/photo/000000121.jpg 空代表无照片(或无此人) 'link_video': link_video, } cdatas.append(cdata) else: print "DATA ERROR" cc={ 'log_id': logid, 'all_id': rtid_all,#无效 'alarm_id': rtid_alarm, 'log_count': log_count,#返回的有效的记录条数,用于改变logid 'data':cdatas, 'door_states':door_states["data"],#门状态数据 } #print "**########**cc=",cc rtdata = simplejson.dumps(cc) return HttpResponse(smart_str(rtdata))