from .models import Spot, Envdata, Alarm, Alarmset, Sms, Sendlog, Device from django.db.models.aggregates import Count from datetime import datetime, timedelta from hashlib import sha1 from .sms import sendSMS from .mail import sendmail SECRET_KEY = '@This is a Secret $tr!' SEND_TIMES = {} FIRST_ALM_TIME = {} COMMAND_QUEUE = [] def deal_post(postdata): spot = None try: sn = postdata['sn'] spot = Spot.objects.get(sn=sn) errcode = int(postdata['errcode']) if postdata['electricity'] == 'True': electricity = 1 else: electricity = 0 fire = int(postdata['fire']) if postdata['water'] == 'True': water = 1 else: water = 0 temperature = float(postdata['temperature']) humidity = float(postdata['humidity']) save_data(spot,errcode,electricity,fire,water,temperature,humidity) except: # record data fail return None if errcode > 0: errvalue = 0 errname = '' if errcode == 2: errvalue = int(temperature) errname = '高温' elif errcode == 3: errvalue = int(humidity) errname = '高湿' elif errcode == 4: errvalue = 0 errname = '断电' elif errcode == 5: errvalue = 1 errname = '漏水' elif errcode == 6: errvalue = fire errname = '火情' elif errcode == 7: errvalue = 0 # network failure 1-online 0-offline errname = '离线' save_alarm(spot, errcode, errname, errvalue) envdata = {'electricity':electricity, 'fire':fire, 'water':water, 'temperature':temperature, 'humidity':humidity} send_alm_message(spot, errcode, errname, errvalue, **envdata) def check_spot(sn): # Check if the spot has recent(within 2 sec) record and return spot id r = True spt = Spot.objects.get(sn=sn) if spt: env = Envdata.objects.filter(spot=spt).order_by('-rectime') if env.exists(): if datetime.now() - env[0].rectime < timedelta(seconds=3): r = False return r def check_token(tkstr): global SECRET_KEY r = False dt = datetime.now() stamp = str(dt.year) + '##' + str(dt.hour%10) m = sha1() m.update((SECRET_KEY + stamp).encode('utf-8')) token = m.hexdigest() # print(token) # print(tkstr) # print(token == tkstr) if token == tkstr: r = True return r def save_data(spot, errcode, electricity, fire, water, temperature, humidity): if spot: Envdata.objects.create(spot=spot,errcode=errcode,electricity=electricity,fire=fire,water=water,temperature=temperature,humidity=humidity,rectime=datetime.now()) return True def save_alarm(spot, errcode, errname, errvalue): if spot: Alarm.objects.create(spot=spot, errcode=errcode, almname=errname, almvalue=errvalue, almtime=datetime.now()) return True def send_alm_message(spot, errcode, errname, errvalue, **envdata): global SEND_TIMES, FIRST_ALM_TIME if not spot: return False if not SEND_TIMES.get(spot.sn): SEND_TIMES[spot.sn] = 0 if not FIRST_ALM_TIME.get(spot.sn): FIRST_ALM_TIME[spot.sn] = datetime.now() triglist = [] # to compare the errcode almset = Alarmset.objects.get(spot=spot) if almset: if almset.connection: triglist.append(7) if almset.fire: triglist.append(6) if almset.water: triglist.append(5) if almset.electricity: triglist.append(4) if almset.temperature: triglist.append(2) if almset.humidity: triglist.append(3) if errcode in triglist and SEND_TIMES[spot.sn] < 3: if SEND_TIMES[spot.sn] == 0: FIRST_ALM_TIME[spot.sn] = datetime.now() elif SEND_TIMES[spot.sn] > 0 and datetime.now() - FIRST_ALM_TIME[spot.sn] < timedelta(seconds=10): return None # get alert person's maillist & phonelist smslist = Sms.objects.all().values_list('phone', flat=True) maillist = Sms.objects.all().values_list('email', flat=True) smstext = '%s机房%s报警,请及时处理。报警代码:%s,报警参数:%s。' % (spot.name, errname, str(errcode), str(errvalue)) mailtext = smstext if envdata: mailtext = mailtext + '\n详细监测参数:漏水-%s 供电-%s 火情-%s 温度-%s 湿度-%s' % (envdata['water'], envdata['electricity'], envdata['fire'], envdata['temperature'], envdata['humidity']) try: if sendSMS(smstext.encode('gb2312'), ','.join(list(smslist))): Sendlog.objects.create(sendtype='sms', sendresult=True, sendtime=datetime.now(), sendto=','.join(list(smslist))) else: Sendlog.objects.create(sendtype='sms', sendresult=False, sendtime=datetime.now(), sendto=','.join(list(smslist))) if sendmail(list(maillist), '机房环境监测报警', mailtext): Sendlog.objects.create(sendtype='mail', sendresult=True, sendtime=datetime.now(), sendto=','.join(list(maillist))) else: Sendlog.objects.create(sendtype='mail', sendresult=False, sendtime=datetime.now(), sendto=','.join(list(maillist))) SEND_TIMES[spot.sn] += 1 except: Sendlog.objects.create(sendtype='sms', sendresult=False, sendtime=datetime.now(), sendto=','.join(list(smslist))) Sendlog.objects.create(sendtype='mail', sendresult=False, sendtime=datetime.now(), sendto=','.join(list(maillist))) if datetime.now() - FIRST_ALM_TIME[spot.sn] > timedelta(hours=1) and SEND_TIMES[spot.sn] >= 3: SEND_TIMES[spot.sn] = 0 return True def get_spots(): spots = Spot.objects.all() return spots def alarm_statics(spot, starttime, endtime): res = Alarm.objects.filter(spot__name=spot,almtime__range=[starttime,endtime]).values('almname').annotate(in_times=Count('almname')) return res def env_statics(spot, tp, starttime, endtime): if not tp: return [] tpdict = {'温度数据':'temperature', '湿度数据':'humidity', '火情数据':'fire', '漏水数据':'water', '断电数据':'electricity'} envdata = Envdata.objects.exclude(temperature=0).exclude(humidity=0) res = envdata.filter(spot__name=spot,rectime__range=[starttime,endtime]).values(tpdict[tp], 'rectime') return res def compre_statics(starttime, endtime): res = Envdata.objects.filter(rectime__range=[starttime,endtime]).values('errcode').annotate(in_times=Count('errcode')).order_by('spot','errcode').values('spot__name','in_times','errcode') # envtag = {'0':'正常', '2':'高温', '3':'高湿', '4':'断电', '5':'漏水', '6':'火情'} spotslist = list(Spot.objects.all().order_by('pk').values_list('name', flat=True)) rlist = [] for spot in spotslist: rlist.append({'spot':spot,'data':[0,0,0,0,0,0,0]}) for spdata in rlist: for rdata in res: if spdata['spot'] == rdata['spot__name']: spdata['data'][rdata['errcode']] = rdata['in_times'] spdata['data'].pop(1) return rlist def parse_spots(spots): lst = [] if spots: for spt in spots: lst.append(spt.name) return lst def get_cmdlist(): # 查询所有未执行的命令列表 global COMMAND_QUEUE return COMMAND_QUEUE def store_cmd(spot, cmd, param): global COMMAND_QUEUE device = Device.objects.filter(spot=spot).first() if cmd!='REBOOT': try: float(param) except: return False if device and cmd != 'REBOOT': # 保持设备的最新状态 # if cmd == 'SERVER_URL': # device.servaddr = param if cmd == 'TIMESPAN': device.timespan = param elif cmd == 'A_FIRE': device.afire = param elif cmd == 'A_TEMP': device.atemp = param elif cmd == 'A_HUM': device.ahum = param device.save() elif not device and cmd != 'REBOOT': dev = Device() if cmd == 'SERVER_URL': dev.servaddr = param elif cmd == 'TIMESPAN': dev.timespan = param elif cmd == 'A_FIRE': dev.afire = param elif cmd == 'A_TEMP': dev.atemp = param elif cmd == 'A_HUM': dev.ahum = param dev.save() COMMAND_QUEUE.append(spot+'$'+cmd+'$'+param) def pop_cmd(spot): global COMMAND_QUEUE c = 'nocmd' if not spot: return c for idx,val in enumerate(COMMAND_QUEUE): if spot in val: c = COMMAND_QUEUE.pop(idx) c = c.replace(spot+'$', '') return c return c def save_deviceinfo(spot, timespan, afire, atemp, ahum): if not spot: return False try: device = Device.objects.filter(spot=spot).first() if not device: device = Device() device.spot = spot # device.servaddr = servaddr device.timespan = timespan device.afire = afire device.atemp = atemp device.ahum = ahum device.save() return True except: return False def get_deviceinfo(spot): deviceinfo = {"TIMESPAN":"","A_FIRE":"","A_TEMP":"","A_HUM":""} if not spot: return deviceinfo dinfo = Device.objects.filter(spot=spot).first() if dinfo: deviceinfo['TIMESPAN'] = str(dinfo.timespan) deviceinfo['A_FIRE'] = str(dinfo.afire) deviceinfo['A_TEMP'] = str(dinfo.atemp) deviceinfo['A_HUM'] = str(dinfo.ahum) return deviceinfo