| 
              # -*- coding: utf-8 -*-
from __future__ import division
import json
import requests
from django.db.models import 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,
                              ThermometerMeasureInfo, ThermometerMeasureLogInfo)
from utils.age import stamp2age
from utils.error.errno_utils import IsolationPointStatusCode, ThermometerEquipmentStatusCode
@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}]
    headers = {
        'Content-Type': 'application/json',
        'Partner-Identifier': 'yingduo',
        'Partner-Token': '9A79C0E34C72B4D0F9B5EA0C59FFC52A',
    }
    for macidsn in macidsns:
        macid, sn = macidsn.get('macid'), macidsn.get('sn')
        data = {
            'mac': macid,
            'callback': 'http://twjc.kodo.com.cn/api/upload/temperature',
        }
        # 设备注册成功
        # {
        #     "ret": "SUCCESS",
        #     "data": {
        #         "id": 6,
        #         "callback": "http://twjc.kodo.com.cn/api/upload/temperature",
        #         "mac": "C4:64:E3:7A:EF:A8"
        #     },
        #     "debug": ""
        # }
        #
        # 设备注册失败
        # {
        #     "ret": "FAIL",
        #     "data": "该设备已被注册!",
        #     "debug": ""
        # }
        try:
            result = requests.post('http://www.protontek.com/vcare-api/open/device/register', headers=headers, data=json.dumps(data)).json()
        except Exception as e:
            result = {'message': e.args}
        ThermometerEquipmentInfo.objects.update_or_create(macid=macid, defaults={
            'point_id': point_id,
            'sn': sn,
            'eqpt_register_status': int(result.get('ret') == 'SUCCESS' or result.get('data') == '该设备已被注册!'),
            'eqpt_register_result': result,
        })
    return response()
@logit
def eqpt_onoff(request):
    macid = request.POST.get('macid', '')
    active = request.POST.get('active', 0)
    ThermometerEquipmentInfo.objects.update_or_create(macid=macid, defaults={
        'active_status': active,
        'active_at': tc.utc_datetime(),
    })
    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)
    macids = eqpts.values_list('macid', flat=True)
    logs = ThermometerMeasureInfo.objects.filter(
        point_id=point_id,
        point_measure_ymd=tc.local_string(format='%Y-%m-%d'),
        point_measure_window=point.point_measure_window,
        macid__in=macids,
        status=True,
    ).values('macid', 'temperature')
    logs = {log.get('macid'): log.get('temperature') for log in logs}
    infos = IsolationPointUserInfo.objects.filter(point_id=point_id, status=True).values('pk', 'fields')
    infos = {info.get('pk'): info.get('fields') for info in infos}
    total_active_eqpt_num = eqpts.count()
    has_upload_temperature_num = len(logs)
    temperature_over_375 = len([1 for temperature in logs.values() if temperature > 37.5])
    if kw:
        eqpts = eqpts.filter(Q(name__icontains=kw) | Q(phone__icontains=kw))
    eqpts, left = pagination(eqpts, page, num)
    eqpts = [{**eqpt.data, **{
        'has_upload': eqpt.macid in logs,
        'temperature': logs.get(eqpt.macid, 0),
        'fields': infos.get(eqpt.ipui_pk, {}),
    }} 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,
        'temperature_over_375': temperature_over_375,
    })
@logit
def upload_temperature(request):
    request.POST = request.POST or json.loads(request.body)
    macid = request.POST.get('mac', '')
    name = request.POST.get('name', '')
    sex = request.POST.get('gender', 0)
    birth_stamp = request.POST.get('birthday', 0)
    age = request.POST.get('age', 0)
    phone = request.POST.get('mobile', '')
    start_stamp = request.POST.get('startTime', 0)
    end_stamp = request.POST.get('endTime', 0)
    temperature = round(float(request.POST.get('maxTempValue', 0)), 2)
    try:
        eqpt = ThermometerEquipmentInfo.objects.get(macid=macid, status=True)
    except ThermometerEquipmentInfo.DoesNotExist:
        ThermometerMeasureLogInfo.objects.create(macid=macid, name=name, sex=sex, birth_stamp=birth_stamp, phone=phone, start_stamp=start_stamp, end_stamp=end_stamp, temperature=temperature, upload_temperature_info=request.POST, status=False)
        return response(ThermometerEquipmentStatusCode.THERMOMETER_EQUIPMENT_NOT_FOUND)
    try:
        point = IsolationPointInfo.objects.get(point_id=eqpt.point_id, status=True)
    except IsolationPointInfo.DoesNotExist:
        return response(IsolationPointStatusCode.ISOLATIONPOINT_NOT_FOUND)
    point_measure_ymd = tc.local_string(format='%Y-%m-%d')
    point_measure_window = point.current_measure_window
    eqpt.name = name
    eqpt.sex = sex
    eqpt.birth_stamp = birth_stamp
    eqpt.age = stamp2age(birth_stamp)
    eqpt.phone = phone
    eqpt.last_submit_at = tc.utc_datetime()
    eqpt.save()
    ThermometerMeasureLogInfo.objects.create(point_id=eqpt.point_id, macid=macid, name=name, sex=sex, birth_stamp=birth_stamp, phone=phone, start_stamp=start_stamp, end_stamp=end_stamp, temperature=temperature, upload_temperature_info=request.POST)
    if point_measure_window:
        measure_info, _ = ThermometerMeasureInfo.objects.get_or_create(point_id=eqpt.point_id, point_measure_ymd=point_measure_ymd, point_measure_window=point_measure_window, macid=macid, defaults={
            'temperature': temperature,
        })
        if temperature > measure_info.temperature:
            measure_info.temperature = temperature
            measure_info.save()
    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
    macid = payload.get('mac', '')
    macid = f'{macid[:2]}:{macid[2:4]}:{macid[4:6]}:{macid[6:8]}:{macid[8:10]}:{macid[10:12]}'
    current_time = payload.get('current_time', '')
    start_stamp = end_stamp = tc.string_to_timestamp(current_time)
    # raw_temp = payload.get('raw_temp', '')
    alg_temp = payload.get('alg_temp', '')
    # temp = raw_temp.split(',') + alg_temp.split(',')
    temp = alg_temp.split(',')
    temp = [int(t) for t in temp if t]
    if not temp:
        return
    temperature = max(temp) / 100
    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
    point_measure_ymd = tc.local_string(format='%Y-%m-%d')
    point_measure_window = point.current_measure_window
    eqpt.last_submit_at = tc.utc_datetime()
    eqpt.save()
    ThermometerMeasureLogInfo.objects.create(point_id=eqpt.point_id, macid=macid, start_stamp=start_stamp, end_stamp=end_stamp, temperature=temperature, temperature_src=ThermometerMeasureLogInfo.MQTT, upload_temperature_info=payload)
    if point_measure_window:
        measure_info, _ = ThermometerMeasureInfo.objects.get_or_create(point_id=eqpt.point_id, point_measure_ymd=point_measure_ymd, point_measure_window=point_measure_window, macid=macid, defaults={
            'temperature': temperature,
        })
        if temperature > measure_info.temperature:
            measure_info.temperature = temperature
            measure_info.save()
 
  |