@@ -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() |
@@ -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 |
+] |
@@ -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) |
@@ -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 |
+ ] |
@@ -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 |