No Description

eqpt_views.py 17KB

    # -*- coding: utf-8 -*- from __future__ import division import json from django.conf import settings from django.db.models import Max, Q from django_logit import logit from django_query import get_query_value from django_response import response from paginator import pagination from TimeConvert import TimeConvert as tc from equipment.models import (IsolationPointInfo, IsolationPointUserInfo, ThermometerEquipmentInfo, ThermometerMeasureLogInfo) from utils.error.errno_utils import IsolationPointStatusCode, ThermometerEquipmentStatusCode from utils.redis.rcharging import get_charging_delta_stamp, set_charging_stamp from utils.redis.rfever import del_fever_stamp, get_fever_delta_stamp, set_fever_stamp from utils.redis.rscreen import get_screen_info, set_screen_info @logit def eqpt_bind(request): point_id = request.POST.get('point_id', '') macid = request.POST.get('macid', '') sn = request.POST.get('sn', '') macidsns = get_query_value(request, 'macidsns', val_cast_type='listjson') macidsns = macidsns or [{'macid': macid, 'sn': sn}] for macidsn in macidsns: macid, sn = macidsn.get('macid'), macidsn.get('sn') ThermometerEquipmentInfo.objects.update_or_create(macid=macid, defaults={ 'point_id': point_id, 'sn': sn, }) return response() @logit def eqpt_onoff(request): macid = request.POST.get('macid', '') active = int(request.POST.get('active', 0)) try: eqpt = ThermometerEquipmentInfo.objects.get(macid=macid) except ThermometerEquipmentInfo.DoesNotExist: return response(ThermometerEquipmentStatusCode.THERMOMETER_EQUIPMENT_NOT_FOUND) if active == 0: try: ipui = IsolationPointUserInfo.objects.get(pk=eqpt.ipui_pk) except IsolationPointUserInfo.DoesNotExist: ipui = None if ipui: ipui.leave_at = tc.utc_datetime() ipui.status = False ipui.save() eqpt.active_status = active eqpt.ipui_pk = 0 eqpt.save() return response() @logit def eqpt_remark(request): macid = request.POST.get('macid', '') remark = request.POST.get('remark', '') try: eqpt = ThermometerEquipmentInfo.objects.get(macid=macid) except ThermometerEquipmentInfo.DoesNotExist: return response(ThermometerEquipmentStatusCode.THERMOMETER_EQUIPMENT_NOT_FOUND) eqpt.remark = remark eqpt.save() # 存放历史备注记录 try: ipui = IsolationPointUserInfo.objects.get(pk=eqpt.ipui_pk) except IsolationPointUserInfo.DoesNotExist: ipui = None if ipui: ipui.remark = remark ipui.remarks += [remark] ipui.save() return response() @logit(body=True) def eqpt_list(request): point_id = request.POST.get('point_id', '') macid = request.POST.get('macid', '') page = request.POST.get('page', 1) num = request.POST.get('num', 20) eqpts = ThermometerEquipmentInfo.objects.filter(point_id=point_id, status=True) if macid: eqpts = eqpts.filter(macid=macid) total_num = eqpts.count() active_num = eqpts.filter(active_status=ThermometerEquipmentInfo.ONLINE).count() eqpts, left = pagination(eqpts, page, num) eqpts = [eqpt.data for eqpt in eqpts] return response(data={ 'eqpts': eqpts, 'left': left, 'total_num': total_num, 'active_num': active_num, 'unactive_num': total_num - active_num, }) @logit def eqpt_result(request): point_id = request.POST.get('point_id', '') kw = request.POST.get('kw', '') page = request.POST.get('page', 1) num = request.POST.get('num', 20) try: point = IsolationPointInfo.objects.get(point_id=point_id, status=True) except IsolationPointInfo.DoesNotExist: return response(IsolationPointStatusCode.ISOLATIONPOINT_NOT_FOUND) eqpts = ThermometerEquipmentInfo.objects.filter(point_id=point_id, active_status=ThermometerEquipmentInfo.ONLINE, status=True) ipuis = IsolationPointUserInfo.objects.filter(point_id=point.point_id, status=True) ipuis = [ipui.data for ipui in ipuis] total_active_eqpt_num = eqpts.count() has_upload_temperature_num = len([1 for ipui in ipuis if ipui.get('temperature_has_upload', '') == IsolationPointUserInfo.HAS_YET_UPLOAD]) fever_num = len([1 for ipui in ipuis if ipui.get('temperature', 0) > settings.FEVER_TEMPERATURE]) ipuis = {ipui.get('pk'): { 'fields': ipui.get('fields', []), 'observed_days': ipui.get('observed_days', 0), 'temperature_has_upload': ipui.get('temperature_has_upload', ''), 'temperature': ipui.get('temperature', 0), 'last_submit_at': ipui.get('last_submit_at', ''), 'remark': ipui.get('remark', ''), } for ipui in ipuis} if kw: eqpts = eqpts.filter(Q(name__icontains=kw) | Q(phone__icontains=kw)) eqpts, left = pagination(eqpts, page, num) eqpts = [{**eqpt.data, **{ 'has_upload': ipuis.get(eqpt.ipui_pk, {}).get('temperature_has_upload', ''), 'temperature': ipuis.get(eqpt.ipui_pk, {}).get('temperature', 0), 'observed_days': ipuis.get(eqpt.ipui_pk, {}).get('observed_days', 0), 'last_submit_at': ipuis.get(eqpt.ipui_pk, {}).get('last_submit_at', ''), 'remark': ipuis.get(eqpt.ipui_pk, {}).get('remark', ''), 'fields': ipuis.get(eqpt.ipui_pk, {}).get('fields', []), }} for eqpt in eqpts] return response(data={ 'eqpts': eqpts, 'left': left, 'total_active_eqpt_num': total_active_eqpt_num, 'has_upload_temperature_num': has_upload_temperature_num, 'not_upload_temperature_num': total_active_eqpt_num - has_upload_temperature_num, 'fever_num': fever_num, }) def protect_user_privacy(field): if (field.get('key', '') == 'phone'): phone = list(field.get('value', '')) phone[3:7] = '****' return ''.join(phone) elif (field.get('key', '') == 'name'): name = list(field.get('value', '')) name[1] = '*' return ''.join(name) return field.get('value', '') def get_screen_data(point=None, point_id=None): if not point: try: point = IsolationPointInfo.objects.get(point_id=point_id, status=True) except IsolationPointInfo.DoesNotExist: return {} # eqpts = ThermometerEquipmentInfo.objects.filter(point_id=point.point_id, active_status=ThermometerEquipmentInfo.ONLINE, status=True) ipuis = IsolationPointUserInfo.objects.filter(point_id=point.point_id, status=True).order_by('-last_submit_at') total_active_eqpt_num = ipuis.count() if point.temperature_measure_type == IsolationPointInfo.SINGLE: start_dt, end_dt = point.match_upload_period ipuis = ipuis.exclude(last_submit_at__range=(start_dt, end_dt), temperature__gt=0.0, temperature__lte=settings.FEVER_TEMPERATURE) ipuis = [{**ipui.data, **{ field.get('key', ''): protect_user_privacy(field) for field in ipui.fields }} for ipui in ipuis] reminds = [{ 'name': ipui.get('name'), 'room': ipui.get('room'), 'content': ipui.get('remark'), } for ipui in ipuis if ipui.get('remark')] ipuis_fever = [] ipuis_not_upload = [] ipuis_unused = [] for ipui in ipuis: temperature = ipui.get('temperature', 0.0) last_submit_at = ipui.get('last_submit_at', '') if not last_submit_at: ipui['temperature'] = '-' ipui['last_report_time'] = '-' ipui['status'] = '未使用' ipuis_unused.append(ipui) continue last_submit_at = tc.make_naive(last_submit_at) if (start_dt < last_submit_at < end_dt) and temperature > settings.FEVER_TEMPERATURE: ipui['status'] = '已上报' ipuis_fever.append(ipui) else: ipui['temperature'] = '-' ipui['status'] = '未测温' ipuis_not_upload.append(ipui) not_upload_temperature_num = len(ipuis_unused) + len(ipuis_not_upload) has_upload_temperature_num = total_active_eqpt_num - not_upload_temperature_num normal_num = has_upload_temperature_num - len(ipuis_fever) return { 'eqpts': ipuis_fever + ipuis_unused + ipuis_not_upload, 'reminds': reminds, 'total_active_eqpt_num': total_active_eqpt_num, 'has_upload_temperature_num': has_upload_temperature_num, 'not_upload_temperature_num': not_upload_temperature_num, 'normal_num': normal_num, 'fever_num': len(ipuis_fever), 'update_time': tc.local_string(), } has_upload_temperature_num = len([1 for ipui in ipuis if ipui.get('temperature_has_upload', '') == IsolationPointUserInfo.HAS_YET_UPLOAD]) fever_num = len([1 for ipui in ipuis if ipui.get('temperature', 0) > settings.FEVER_TEMPERATURE and ipui.get('temperature_has_upload') == IsolationPointUserInfo.HAS_YET_UPLOAD]) # ipuis = {ipui.get('pk'): { # 'fields': ipui.get('fields', []), # 'observed_days': ipui.get('observed_days', 0), # 'user_status': ipui.get('user_status', ''), # 'temperature': ipui.get('temperature', 0), # 'last_submit_at': ipui.get('last_submit_at', ''), # 'remark': ipui.get('remark', ''), # } for ipui in ipuis} eqpts = ipuis # eqpts = [{**{ # 'user_status': ipuis.get(eqpt.ipui_pk, {}).get('user_status', ''), # 'temperature': ipuis.get(eqpt.ipui_pk, {}).get('temperature', 0), # 'observed_days': ipuis.get(eqpt.ipui_pk, {}).get('observed_days', 0), # 'last_submit_at': ipuis.get(eqpt.ipui_pk, {}).get('last_submit_at', ''), # 'remark': ipuis.get(eqpt.ipui_pk, {}).get('remark', ''), # }, **{ # field.get('key', ''): field.get('value', '') for field in ipuis.get(eqpt.ipui_pk, {}).get('fields', []) # }} for eqpt in eqpts] # eqpts = [{ # 'name': eqpt.get('name', ''), # 'room': eqpt.get('room', ''), # 'phone': eqpt.get('phone', ''), # 'sex': eqpt.get('sex', ''), # 'age': eqpt.get('age', ''), # 'status': eqpt.get('user_status'), # 'last_report_time': eqpt.get('last_submit_at', ''), # 'temperature': eqpt.get('temperature', 0), # 'observed_days': eqpt.get('observed_days', 0), # } for eqpt in eqpts] # 排序:发烧 > 未联网 > 关机 > 未佩戴 > 充电中 > 时间 eqpts_fever = [] # eqpts_not_upload = [] eqpts_not_connected = [] eqpts_shutdown = [] eqpts_not_worn = [] eqpts_chg = [] eqpts_other = [] for eqpt in eqpts: status = eqpt.get('status') temperature = eqpt.get('temperature') if status == IsolationPointUserInfo.HAS_YET_UPLOAD and temperature > settings.FEVER_TEMPERATURE: eqpts_fever.append(eqpt) elif status == IsolationPointUserInfo.HAS_NOT_CONNECTED: eqpt['temperature'] = '-' eqpts_not_connected.append(eqpt) elif status == IsolationPointUserInfo.HAS_SHUTDOWN: eqpt['temperature'] = '-' eqpts_shutdown.append(eqpt) elif status == IsolationPointUserInfo.HAS_NOT_WORN: eqpt['temperature'] = '-' eqpts_not_worn.append(eqpt) elif status == IsolationPointUserInfo.CHG_STA_CHARGING: eqpt['temperature'] = '-' eqpts_chg.append(eqpt) else: eqpts_other.append(eqpt) return { 'eqpts': eqpts_fever + eqpts_not_connected + eqpts_shutdown + eqpts_not_worn + eqpts_chg + eqpts_other, 'reminds': reminds, 'total_active_eqpt_num': total_active_eqpt_num, 'has_upload_temperature_num': has_upload_temperature_num, 'not_upload_temperature_num': total_active_eqpt_num - has_upload_temperature_num, 'normal_num': has_upload_temperature_num - fever_num, 'fever_num': fever_num, 'update_time': tc.local_string(), } @logit def screen_eqpt_result(request): point_id = request.POST.get('point_id', '') screen_info = get_screen_info(point_id) if screen_info: return response(data=screen_info) try: point = IsolationPointInfo.objects.get(point_id=point_id, status=True) except IsolationPointInfo.DoesNotExist: return response(IsolationPointStatusCode.ISOLATIONPOINT_NOT_FOUND) screen_data = get_screen_data(point) return response(data=screen_data) @logit def upload_temperature(request): return response() def mqtt_upload_temperature(payload): # Received `{"mac":"A4DA324E7A63","pkt":"215","chg_sta":true,"bat":"100","raw_temp":"4697,4696,4697","sta":"0","alg_temp":"4697,4696,4697","alg_gstr":0,"ble_rssi":-21,"wifi_rssi":-68,"current_time":"2021-08-08 15:22:59"}` from `esp/240AC4D3C1AC` topic # # { # "mac": "A4DA324E7A63", # 体温贴 mac,固定 6 个字节,12 个字符 # "pkt": "215", # 广播包包序为 85,有效包序范围[1, 255] # "chg_sta": true, # 充电状态,true 充电,false 未充电 # "bat": "100", # 电量剩余 65%,有效电量范围[0, 100] # "raw_temp": "4697,4696,4697", # 三个原始温度数 # "sta": "0", # 算法返回状态 # "alg_temp": "4697,4696,4697", # 算法返回三个温度 # "alg_gstr": 0, # 算法手臂姿态 # "ble_rssi": -21, # 体温贴相对于底座的信号强度 # "wifi_rssi": -68, # 底座网络信号强度 # "current_time": "2021-08-08 15:22:59" # 底座接收到体温贴信息的实时时间 # } try: payload = json.loads(payload) except Exception: return alg_temp = payload.get('alg_temp', '') temp = alg_temp.split(',') temp = [int(t) for t in temp if t] if not temp: return temperature = max(temp) / 100 # 充电状态,true 充电,false 未充电 chg_sta = payload.get('chg_sta', False) # 电量剩余 65%,有效电量范围[0, 100] bat = int(payload.get('bat', 0)) # 体温贴 mac,固定 6 个字节,12 个字符 macid = payload.get('mac', '') macid = f'{macid[:2]}:{macid[2:4]}:{macid[4:6]}:{macid[6:8]}:{macid[8:10]}:{macid[10:12]}' # 充电状态 or (电量剩余 100% + 温度超过 37 度),温度忽略 ignore_temperature = False if chg_sta or (bat == 100 and temperature > 37): ignore_temperature = True chg_sta = True set_charging_stamp(macid) # 过去半小时内如果有充电记录的,当前温度大于37度的过滤掉 if temperature > 37 and get_charging_delta_stamp(macid) < 1800: ignore_temperature = True # 过去10分钟连续大于37.3度再取最高温度 ignore_fever_temperature = False if not ignore_temperature and temperature > settings.FEVER_TEMPERATURE: delta_stamp = get_fever_delta_stamp(macid) # 首次超过37.3 if not delta_stamp: set_fever_stamp(macid) ignore_fever_temperature = True # 连续10分钟超过37.3 elif delta_stamp > 600: pass else: ignore_fever_temperature = True else: del_fever_stamp(macid) current_time = payload.get('current_time', '') start_stamp = end_stamp = tc.string_to_timestamp(current_time) try: eqpt = ThermometerEquipmentInfo.objects.get(macid=macid, status=True) except ThermometerEquipmentInfo.DoesNotExist: # ThermometerMeasureLogInfo.objects.create(macid=macid, start_stamp=start_stamp, end_stamp=end_stamp, temperature=temperature, temperature_src=ThermometerMeasureLogInfo.MQTT, upload_temperature_info=payload, status=False) return try: point = IsolationPointInfo.objects.get(point_id=eqpt.point_id, status=True) except IsolationPointInfo.DoesNotExist: return # # 非配置的隔离点上报时间内 # if not point.match_upload_period: # return ThermometerMeasureLogInfo.objects.create(point_id=eqpt.point_id, macid=macid, start_stamp=start_stamp, end_stamp=end_stamp, temperature=temperature, temperature_src=ThermometerMeasureLogInfo.MQTT, chg_sta=chg_sta, ignore_temperature=ignore_temperature, ignore_fever_temperature=ignore_fever_temperature, upload_temperature_info=payload) try: ipui = IsolationPointUserInfo.objects.get(pk=eqpt.ipui_pk) except IsolationPointUserInfo.DoesNotExist: ipui = None if ipui: if not ignore_temperature: temperature__max = ThermometerMeasureLogInfo.objects.filter( point_id=eqpt.point_id, macid=macid, chg_sta=False, ignore_temperature=False, ignore_fever_temperature=False, created_at__gte=tc.utc_datetime(hours=-1), ).aggregate(Max('temperature')).get('temperature__max') or 0 ipui.observed_ymds = list(set(ipui.observed_ymds + [tc.local_string(format='%Y-%m-%d')])) ipui.observed_days = len(ipui.observed_ymds) ipui.temperature = temperature__max or ipui.temperature ipui.last_submit_at = tc.utc_datetime() ipui.chg_sta = chg_sta ipui.save() set_screen_info(point.point_id, get_screen_data(point))