:sparkles: Add /api/v2/upload/temperature

huangqimin001 3 ans auparavant
Parent
Commettre
82c5285240
5 fichiers modifiés avec 141 ajouts et 6 suppressions
  1. 50 0
      api/aep_views.py
  2. 7 1
      api/urls.py
  3. 7 2
      equipment/admin.py
  4. 32 0
      equipment/migrations/0023_aepthermometermeasureloginfo.py
  5. 45 3
      equipment/models.py

+ 50 - 0
api/aep_views.py

@@ -0,0 +1,50 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+from __future__ import division
4
+
5
+import base64
6
+import json
7
+
8
+from django_logit import logit
9
+from django_query import get_query_value
10
+from django_response import response
11
+
12
+from equipment.models import AepThermometerMeasureLogInfo
13
+
14
+
15
+@logit
16
+def aep_upload_temperature(request):
17
+    # {
18
+    #     "upPacketSN": -1,
19
+    #     "upDataSN": -1,
20
+    #     "topic": "v1/up/ad",
21
+    #     "timestamp": 1636096959410,
22
+    #     "tenantId": "2000051017",
23
+    #     "serviceId": "",
24
+    #     "protocol": "lwm2m",
25
+    #     "productId": "15091846",
26
+    #     "payload": {
27
+    #         "APPdata": "MjIyMzk0"
28
+    #     },
29
+    #     "messageType": "dataReport",
30
+    #     "deviceType": "",
31
+    #     "deviceId": "6b34c9d2d06b4965b4fe505e6d6c342c",
32
+    #     "assocAssetId": "",
33
+    #     "IMSI": "460113179251578",
34
+    #     "IMEI": "355558100904547"
35
+    # }
36
+    reqdata = request.POST or json.loads(request.body)
37
+    imei = reqdata.get('IMEI', '')
38
+    payload = reqdata.get('payload') or {}
39
+    appdata = payload.get('APPdata', '')
40
+
41
+    appdata = base64.decodebytes(appdata.encode()).hex()
42
+
43
+    AepThermometerMeasureLogInfo.objects.create(
44
+        imei=imei,
45
+        upload_temperature_info=reqdata,
46
+        temperature_info=[appdata[:2], appdata[2:4], appdata[4:6]],
47
+        battery_info=[appdata[6:8], appdata[8:10], appdata[10:12]],
48
+    )
49
+
50
+    return response()

+ 7 - 1
api/urls.py

@@ -2,7 +2,8 @@
2 2
 
3 3
 from django.conf.urls import url
4 4
 
5
-from api import admin_views, eqpt_views, field_views, mini_views, oauth_views, point_views, screen_views, wx_views
5
+from api import (admin_views, aep_views, eqpt_views, field_views, mini_views, oauth_views, point_views, screen_views,
6
+                 wx_views)
6 7
 
7 8
 
8 9
 urlpatterns = [
@@ -67,3 +68,8 @@ urlpatterns += [
67 68
 
68 69
     url(r'^screen/eqpt/result$', eqpt_views.screen_eqpt_result, name='screen_eqpt_result'),
69 70
 ]
71
+
72
+# AEP
73
+urlpatterns += [
74
+    url(r'^v2/upload/temperature$', aep_views.aep_upload_temperature, name='aep_upload_temperature'),
75
+]

+ 7 - 2
equipment/admin.py

@@ -3,8 +3,8 @@
3 3
 from django.contrib import admin
4 4
 from django_admin import ReadOnlyModelAdmin
5 5
 
6
-from equipment.models import (IsolationPointFieldPoolInfo, IsolationPointInfo, IsolationPointUserInfo,
7
-                              ThermometerEquipmentInfo, ThermometerMeasureLogInfo)
6
+from equipment.models import (AepThermometerMeasureLogInfo, IsolationPointFieldPoolInfo, IsolationPointInfo,
7
+                              IsolationPointUserInfo, ThermometerEquipmentInfo, ThermometerMeasureLogInfo)
8 8
 
9 9
 
10 10
 class IsolationPointFieldPoolInfoAdmin(admin.ModelAdmin):
@@ -29,8 +29,13 @@ class ThermometerMeasureLogInfoAdmin(ReadOnlyModelAdmin, admin.ModelAdmin):
29 29
     list_filter = ('point_id', 'temperature_src', 'chg_sta', 'ignore_temperature', 'ignore_fever_temperature', 'status')
30 30
 
31 31
 
32
+class AepThermometerMeasureLogInfoAdmin(ReadOnlyModelAdmin, admin.ModelAdmin):
33
+    list_display = ('imei', 'temperature_src', 'temperature_info', 'battery_info', 'status', 'created_at', 'updated_at')
34
+
35
+
32 36
 admin.site.register(IsolationPointFieldPoolInfo, IsolationPointFieldPoolInfoAdmin)
33 37
 admin.site.register(IsolationPointInfo, IsolationPointInfoAdmin)
34 38
 admin.site.register(IsolationPointUserInfo, IsolationPointUserInfoAdmin)
35 39
 admin.site.register(ThermometerEquipmentInfo, ThermometerEquipmentInfoAdmin)
36 40
 admin.site.register(ThermometerMeasureLogInfo, ThermometerMeasureLogInfoAdmin)
41
+admin.site.register(AepThermometerMeasureLogInfo, AepThermometerMeasureLogInfoAdmin)

+ 32 - 0
equipment/migrations/0023_aepthermometermeasureloginfo.py

@@ -0,0 +1,32 @@
1
+# Generated by Django 3.2.7 on 2021-11-22 07:31
2
+
3
+from django.db import migrations, models
4
+import jsonfield.fields
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('equipment', '0022_thermometermeasureloginfo_ignore_fever_temperature'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.CreateModel(
15
+            name='AepThermometerMeasureLogInfo',
16
+            fields=[
17
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
18
+                ('status', models.BooleanField(default=True, help_text='Status', verbose_name='status')),
19
+                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
20
+                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
21
+                ('imei', models.CharField(blank=True, db_index=True, help_text='IMEI', max_length=32, null=True, verbose_name='imei')),
22
+                ('temperature_src', models.IntegerField(choices=[(1, '接口回调'), (2, 'MQTT')], default=1, help_text='用户体温来源', verbose_name='temperature_src')),
23
+                ('upload_temperature_info', jsonfield.fields.JSONField(blank=True, help_text='测温结果上传信息', null=True, verbose_name='upload_temperature_info')),
24
+                ('temperature_info', jsonfield.fields.JSONField(blank=True, help_text='温度信息', null=True, verbose_name='temperature_info')),
25
+                ('battery_info', jsonfield.fields.JSONField(blank=True, help_text='电量信息', null=True, verbose_name='battery_info')),
26
+            ],
27
+            options={
28
+                'verbose_name': 'AEP测温记录信息',
29
+                'verbose_name_plural': 'AEP测温记录信息',
30
+            },
31
+        ),
32
+    ]

+ 45 - 3
equipment/models.py

@@ -123,7 +123,6 @@ class IsolationPointUserInfo(BaseModelMixin):
123 123
             return IsolationPointUserInfo.CHG_STA_CHARGING
124 124
         if self.last_submit_at and self.last_submit_at > tc.utc_datetime(hours=-1):
125 125
             return IsolationPointUserInfo.HAS_YET_UPLOAD
126
-        
127 126
         return IsolationPointUserInfo.HAS_NOT_UPLOAD
128 127
 
129 128
     @property
@@ -137,10 +136,8 @@ class IsolationPointUserInfo(BaseModelMixin):
137 136
             return IsolationPointUserInfo.HAS_NOT_WORN
138 137
         if not has_upload and (self.chg_sta or self.temperature > 0):
139 138
             return IsolationPointUserInfo.HAS_SHUTDOWN
140
-        
141 139
         return IsolationPointUserInfo.HAS_NOT_CONNECTED
142 140
 
143
-
144 141
     @property
145 142
     def data(self):
146 143
         return {
@@ -252,3 +249,48 @@ class ThermometerMeasureLogInfo(BaseModelMixin):
252 249
             'sn': self.sn,
253 250
             'temperature': self.temperature,
254 251
         }
252
+
253
+
254
+class AepThermometerMeasureLogInfo(BaseModelMixin):
255
+    # {
256
+    #     "upPacketSN": -1,
257
+    #     "upDataSN": -1,
258
+    #     "topic": "v1/up/ad",
259
+    #     "timestamp": 1636096959410,
260
+    #     "tenantId": "2000051017",
261
+    #     "serviceId": "",
262
+    #     "protocol": "lwm2m",
263
+    #     "productId": "15091846",
264
+    #     "payload": {
265
+    #         "APPdata": "MjIyMzk0"
266
+    #     },
267
+    #     "messageType": "dataReport",
268
+    #     "deviceType": "",
269
+    #     "deviceId": "6b34c9d2d06b4965b4fe505e6d6c342c",
270
+    #     "assocAssetId": "",
271
+    #     "IMSI": "460113179251578",
272
+    #     "IMEI": "355558100904547"
273
+    # }
274
+
275
+    CALLBACK = 1
276
+    MQTT = 2
277
+
278
+    TEMPERATURE_SRC_TUPLE = (
279
+        (CALLBACK, '接口回调'),
280
+        (MQTT, 'MQTT'),
281
+    )
282
+
283
+    imei = models.CharField(_('imei'), max_length=32, blank=True, null=True, help_text='IMEI', db_index=True)
284
+
285
+    temperature_src = models.IntegerField(_('temperature_src'), choices=TEMPERATURE_SRC_TUPLE, default=CALLBACK, help_text='用户体温来源')
286
+    upload_temperature_info = JSONField(_('upload_temperature_info'), blank=True, null=True, help_text='测温结果上传信息')
287
+
288
+    temperature_info = JSONField(_('temperature_info'), blank=True, null=True, help_text='温度信息')
289
+    battery_info = JSONField(_('battery_info'), blank=True, null=True, help_text='电量信息')
290
+
291
+    class Meta:
292
+        verbose_name = _('AEP测温记录信息')
293
+        verbose_name_plural = _('AEP测温记录信息')
294
+
295
+    def __unicode__(self):
296
+        return self.pk