From 384b4d35804cdc301d170ffb401f2eb941778cef Mon Sep 17 00:00:00 2001 From: Alan Mitchell Date: Thu, 11 Jul 2019 09:31:18 -0800 Subject: [PATCH] Added method to store HTTP Integration data from Things Network. --- bmsapp/urls.py | 3 ++- bmsapp/views.py | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/bmsapp/urls.py b/bmsapp/urls.py index c3845ca..c09d6d0 100644 --- a/bmsapp/urls.py +++ b/bmsapp/urls.py @@ -7,10 +7,11 @@ from django.urls import re_path from . import views from . import views_api_v1 -# Could work on simplifying many of these by usin the new "path" function +# Could work on simplifying many of these by using the new "path" function urlpatterns = [ re_path(r'^readingdb/reading/(\w+)/store/$', views.store_reading), # URL to store one reading into database re_path(r'^readingdb/reading/store/$', views.store_readings), # URL to store multiple readings into database + re_path(r'^readingdb/reading/store-things/$', views.store_readings_things), # URL to store readings from Things Network re_path(r'^st8(\w+)/', views.store_reading_old), # Old URL pattern for storing. Shouldn't be used for new sensors. re_path(r'^readingdb/reading/(\w+)/$', views.get_readings), # gets all readings for one reading ID. re_path(r'^$', views.index, name='index'), diff --git a/bmsapp/views.py b/bmsapp/views.py index a5d8612..2da5c79 100644 --- a/bmsapp/views.py +++ b/bmsapp/views.py @@ -1,6 +1,8 @@ # Create your views here. import sys, logging, json, random, time +import dateutil.parser + from django.http import HttpResponse from django.shortcuts import render_to_response, redirect, render from django.contrib.auth.decorators import login_required @@ -237,6 +239,52 @@ def store_readings(request): _logger.exception('Error Storing Reading') return HttpResponse(sys.exc_info()[1]) +# Payload Fields from Things Network nodes that do not contain sensor +# readings. +EXCLUDE_THINGS_FIELDS = ('event', ) + +@csrf_exempt # needed to accept HTTP POST requests from systems other than this one. +def store_readings_things(request): + ''' + Stores a set of sensor readings from the Things Network in the sensor reading + database. The readings are assumed to originate from an HTTP Integration on an + Application in the Things Network. The Authorization header in the request contains + the BMON Store Key. The readings and other data are in the POST data encoded in JSON. + ''' + try: + + # The post data is JSON, so decode it. + req_data = json.loads(request.body) + + # Return if this is a message that does not have any data in it, like an + # activate or join message. + if 'payload_fields' not in req_data: + return HttpResponse('No Data') + + # See if the store key is valid. The Authorization header is of the format: + # BMON + try: + _, storeKey = request.META['HTTP_AUTHORIZATION'].split() + except: + storeKey = 'None_Present' + + if store_key_is_valid(storeKey): + readings = [] + ts = dateutil.parser.parse(req_data['metadata']['time']).timestamp() + hdw_serial = req_data['hardware_serial'] + for fld, val in req_data['payload_fields'].items(): + if fld not in EXCLUDE_THINGS_FIELDS: + readings.append( [ts, f'{hdw_serial}_{fld}', val] ) + msg = storereads.store_many({'readings': readings}) + return HttpResponse(msg) + else: + _logger.warning('Invalid Storage Key in Reading Post: %s', storeKey) + return HttpResponse('Invalid Key') + + except: + _logger.exception('Error Storing Reading') + return HttpResponse(sys.exc_info()[1]) + @csrf_exempt def store_reading_old(request, store_key): ''' -- 2.26.2