You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
265 lines
9.5 KiB
265 lines
9.5 KiB
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
|