def total_energy_view(request): owner = djutils.get_requested_user(request) meter, channel = sdutils.get_meter(owner) form = IntervalForm(request.GET) if not form.is_valid(): return HttpResponseBadRequest(get_json_error(dict(form.errors))) start = form.cleaned_data['start'] end = form.cleaned_data['end'] if start >= end: return HttpResponseBadRequest( get_json_error('invalid interval requested')) data_start = SensorReading.objects.filter( sensor=meter, channel=channel).aggregate(Min('timestamp'))['timestamp__min'] data_end = SensorReading.objects.filter( sensor=meter, channel=channel).aggregate(Max('timestamp'))['timestamp__max'] data_end += timedelta(seconds=channel.reading_frequency) start = max(start, data_start) end = min(end, data_end) #filter the reading list for the selection period reading_list = SensorReading.objects.filter(sensor=meter, channel=channel) reading_list = reading_list.filter(timestamp__gte=(start)) reading_list = reading_list.filter(timestamp__lt=(end)) total_energy = reading_list.aggregate(Sum('value'))['value__sum'] return HttpResponse(json.dumps(total_energy))
def meter_reading_view(request, data_type): djutils.log_request('meter_reading_view', request) form = SampledIntervalForm(request.GET) if not form.is_valid(): return HttpResponseBadRequest(get_json_error(dict(form.errors))) meter_owner = djutils.get_requested_user(request) try: meter = Sensor.objects.get(id=request.GET['m_ID']) except KeyError: meter, _ = sdutils.get_meter(meter_owner) channel = Channel.objects.get(name='energy') requested_interval = form.cleaned_data['sampling_interval'] start = form.cleaned_data['start'] end = form.cleaned_data['end'] if start >= end: return HttpResponseBadRequest( get_json_error('invalid interval requested')) #filter by interval #reading_list_gen = filter_according_to_interval_gen(meter, start, end, requested_interval, data_type) #reading_list_gen = list(reading_list_gen) #logger.debug('gen: ' + str([x.value for x in reading_list_gen[:4]])) #reading_list_sql = filter_according_to_interval_sql(meter, start, end, requested_interval, data_type) reading_list = sdutils.filter_according_to_interval( meter, channel, start, end, requested_interval, data_type) result = {} result['data'] = [{ 't': 1000 * mktime(x.timestamp.timetuple()), 'value': x.value } for x in reading_list] if len(result['data']) == 0: #raise SensorReading.DoesNotExist('no sensor readings') result['max_datetime'] = 0 result['min_datetime'] = 0 return HttpResponse(json.dumps(result)) min_datetime = SensorReading.objects.filter( sensor=meter, channel=channel).aggregate(Min('timestamp'))['timestamp__min'] min_datetime = min_datetime.strftime(djutils.DATE_FMTS[0]) result['min_datetime'] = min_datetime max_datetime = SensorReading.objects.filter( sensor=meter, channel=channel).aggregate(Max('timestamp'))['timestamp__max'] max_datetime = max_datetime.strftime(djutils.DATE_FMTS[0]) result['max_datetime'] = max_datetime return HttpResponse(json.dumps(result))
def login_view(request): if request.method == "POST": u = request.POST['username'] p = request.POST['password'] user = authenticate(username=u, password=p) if user != None: login(request, user) return HttpResponse( json.dumps({ 'status': 'success', 'user_id': user.id })) else: return HttpResponseBadRequest( djutils.get_json_error( json.dumps({'status': 'bad username or password'}))) return HttpResponseBadRequest(djutils.get_json_error("NOT_POST_REQUEST"))
def always_on_view(request, data_type): meter_owner = djutils.get_requested_user(request) print("Request params:", request.GET.keys()) if request.GET.get('m_ID', None) == None: meter, _ = sdutils.get_meter(meter_owner) else: meter = Sensor.objects.get(id=request.GET['m_ID']) channel = Channel.objects.get(name='energy') form = SampledIntervalForm(request.GET) if not form.is_valid(): return HttpResponseBadRequest(get_json_error(dict(form.errors))) requested_interval = form.cleaned_data['sampling_interval'] start = form.cleaned_data['start'] end = form.cleaned_data['end'] if start >= end: return HttpResponseBadRequest( get_json_error('invalid interval requested')) sr = SensorReading.objects.filter(sensor=meter, channel=channel) if not (sr.exists()): return HttpResponse(json.dumps([])) data_start = sr.aggregate(Min('timestamp'))['timestamp__min'] data_end = sr.aggregate(Max('timestamp'))['timestamp__max'] data_end += timedelta(seconds=channel.reading_frequency) start = max(start, data_start) end = min(end, data_end) baseline = sdutils.calculate_always_on(meter, channel, start, end, requested_interval, data_type) baseline = [{ 't': 1000 * mktime(x[0].timetuple()), 'value': x[1] } for x in baseline] return HttpResponse(json.dumps(baseline))
def _wrapped_view(request, *args, **kwargs): if request.user.is_authenticated(): # does the request contain a user? owner = request.user # can the user access the data? if can_access_user_data(owner, request.user): return view_func(request, *args, **kwargs) else: return HttpResponseForbidden(get_json_error('ACCESS_DENIED')) path = request.build_absolute_uri() # If the login url is the same scheme and net location then just # use the path as the "next" url. login_scheme, login_netloc = urlparse.urlparse(login_url or settings.LOGIN_URL)[:2] current_scheme, current_netloc = urlparse.urlparse(path)[:2] if ((not login_scheme or login_scheme == current_scheme) and (not login_netloc or login_netloc == current_netloc)): path = request.get_full_path() return redirect_to_login(path, login_url, redirect_field_name)
def meter_view(request, meter_id=None): if request.method == "GET": if meter_id == None: owner = djutils.get_requested_user(request) meter_list = Meter.objects.filter(user=owner) return HttpResponse(json.dumps([to_dict(x) for x in meter_list])) else: meter_list = (Meter.objects.get(id=meter_id), ) if meter_list[0].user != djutils.get_requested_user(request): return HttpResponse( "Tried to access a meter from a different user than the authenticated user.", status=403) return HttpResponse(json.dumps([to_dict(m) for m in meter_list])) elif request.method == "POST": raise NotImplementedError else: return HttpResponseBadRequest( djutils.get_json_error("NOT_GET_REQUEST"))
def raw_data_view(request, sensor_mac, channel_name): # key: string # value: float # Get sensor and channel sensor = get_object_or_404(Sensor, mac=sensor_mac) try: channel = sensor.channels.get(name=channel_name) except Channel.DoesNotExist: return HttpResponseNotFound( "This sensor does not appear to contain that channel.") form = RawDataForm(request.POST) if not form.is_valid(): return HttpResponseBadRequest(djutils.get_json_error(dict( form.errors))) dt = datetime.now() key_string = form.cleaned_data['key'] value = form.cleaned_data['value'] # check that the key matches the sensor try: key = RawDataKey.objects.get(value=key_string) if not sensor in key.sensors.all(): return HttpResponse('Unauthorized', status=401) except RawDataKey.DoesNotExist: return HttpResponse('Unauthorized', status=401) reading, created = SensorReading.objects.get_or_create( sensor=sensor, channel=channel, timestamp=dt, defaults={'value': value}) if not created: reading.value = value reading.save() return HttpResponse(djutils.get_json_success(True))
def total_energy_cost_view(request): owner = djutils.get_requested_user(request) meter, channel = sdutils.get_meter(owner) form = IntervalForm(request.GET) if not form.is_valid(): return HttpResponseBadRequest(get_json_error(dict(form.errors))) start = form.cleaned_data['start'] end = form.cleaned_data['end'] if start >= end: return HttpResponseBadRequest( get_json_error('invalid interval requested')) data_start = SensorReading.objects.filter( sensor=meter, channel=channel).aggregate(Min('timestamp'))['timestamp__min'] data_end = SensorReading.objects.filter( sensor=meter, channel=channel).aggregate(Max('timestamp'))['timestamp__max'] data_end += timedelta(seconds=channel.reading_frequency) start = max(start, data_start) end = min(end, data_end) #filter the reading list for the selection period reading_list = SensorReading.objects.filter(sensor=meter, channel=channel) reading_list = reading_list.filter(timestamp__gte=(start)) reading_list = reading_list.filter(timestamp__lte=(end)) total_energy = reading_list.aggregate(Sum('value'))['value__sum'] always_on_readings = sdutils.calculate_always_on(meter, channel, start, end, 120, 'energy') always_on = sum([x[1] for x in always_on_readings]) # logger.debug('energy count: %d, always_on count: %d' % (reading_list.count(), len(always_on_readings))) # logger.debug('start: %s, end: %s' % (start, end)) # logger.debug('data_start: %s, data_end: %s' % (data_start, data_end)) # TODO: this introduces a dependency -- this is to be considered # a temporary implementation and a cleaner solution should be found # to make the code more properly modular try: from pricing import combined #@UnresolvedImport prices = combined.get_actual_prices(start, end, 0.5, 0.5) # TODO make this more precise avg_price = sum(prices) / float(len(prices)) total_cost = total_energy * avg_price always_on_cost = always_on * avg_price except Exception as e: logger.error('pricing exception: ' + str(e)) total_cost = 0 always_on_cost = 0 result = {} result['total_cost'] = total_cost result['always_on_cost'] = always_on_cost result[ 'variable_load_cost'] = result['total_cost'] - result['always_on_cost'] return HttpResponse(json.dumps(result))
def event_view(request, event_id=None): djutils.log_request('event_view %s' % (str(event_id)), request) logger.debug('event_view') owner = djutils.get_requested_user(request) #startTime = time.clock() if request.method == "GET": # if the user is part of the control group return no events # if Group.objects.get(name='control') in request.user.groups.all(): # return HttpResponse(json.dumps([])) if event_id != None: event = Event.objects.get(id=event_id) # augment json with baseline, max, consumption and data event_dict = sdutils.calculate_event(event) return HttpResponse(json.dumps(event_dict)) else: logger.debug('entered else') # event_id not specified # get all events within interval form = IntervalForm(request.GET) if not form.is_valid(): return HttpResponseBadRequest(get_json_error(dict( form.errors))) start = form.cleaned_data['start'] end = form.cleaned_data['end'] if start >= end: return HttpResponseBadRequest( get_json_error('invalid interval requested')) # filter by user events = Event.objects.filter(sensor__user=owner) events = events.filter(end__gte=start) events = events.filter(start__lte=end) # exclude suggestions overlapping events sugg_type = EventType.objects.get(name='question mark') # check that there are no overlapping events from the same user manual_events = Event.objects.filter(sensor__user=owner).filter( end__gte=start).filter(start__lte=end).exclude( event_type=sugg_type) # TODO: fix this! logger.debug('about to enter for loop') for ev in manual_events: # start < sugg.start < end events = events.exclude(event_type=sugg_type, start__gte=ev.start, start__lte=ev.end) # start < sugg.end < end events = events.exclude(event_type=sugg_type, end__gte=ev.start, end__lte=ev.end) # start < sugg.start < sugg.end < end events = events.exclude(event_type=sugg_type, start__lte=ev.start, end__gte=ev.end) events = events.exclude(event_type=sugg_type, start__gte=ev.start, end__lte=ev.end) logger.debug('about to call sdutils.calculate_event') events = [sdutils.calculate_event(ev) for ev in events] logger.debug('sdutils.calculate_event returned') return HttpResponse(json.dumps(events)) elif request.method == "POST": event = None if event_id != None: event = Event.objects.get(id=event_id) # TODO: use a form for validation form = EventForm(request.POST, instance=event) if not form.is_valid(): return HttpResponseBadRequest(get_json_error(dict(form.errors))) event = form.save(commit=False) #event.user = owner #sensor = Sensor.objects.get(id=request) event.event_type = EventType.objects.get( id=form.cleaned_data['event_type_id']) # check that there are no overlapping events from the same user dupes = Event.objects.filter(sensor__user=owner).exclude(id=event.id) # except suggestions! dupes = dupes.exclude(event_type=EventType.objects.get( name='question mark')) dupes1 = dupes.filter(start__gte=event.start).filter( start__lte=event.end) dupes2 = dupes.filter(end__gte=event.start).filter(end__lte=event.end) if dupes1.count() + dupes2.count() > 0: return HttpResponseBadRequest( get_json_error('overlapping event exists')) event.save() #FigureEnergy.recognition.data_interface.extractFeaturesFromDBEvent(event) event_created.send(Event.objects, event=event) #event.start = datetime.utcfromtimestamp(int(float(request.POST['start']))) #event.end = datetime.utcfromtimestamp(int(float(request.POST['end']))) #event.name = request.POST['name'] #event.description = request.POST['description'] #typeID = request.POST.get('event_type') #event.type = EventType.objects.get(id=typeID) #event.consumption = 0 #event.baseline = 0 #event.save() # if request.POST.get('metering_points_array', None) != None: # metering_point_ids = eval(request.POST.get('metering_points_array', None)) # metering_points_found = [] # for metering_point_id in metering_point_ids: # try: # metering_point = MeteringPoint.objects.get(id = metering_point_id) # metering_points_found.append(metering_point) # except MeteringPoint.DoesNotExist: # pass # event.metering_points = metering_points_found # event.save() return HttpResponse(get_json_success(event.id)) elif request.method == "DELETE": event = Event.objects.get(id=event_id) if event.sensor.user == owner: event_id = event.id event.delete() return HttpResponse(get_json_success(event_id)) return HttpResponseForbidden(get_json_error("ACCESS_DENIED")) else: return HttpResponseBadRequest( get_json_error("NOT_GET_POST_OR_DELETE_REQUEST"))
def annotation_view(request, annotation_id=None): owner = djutils.get_requested_user(request) if request.method == "GET": if annotation_id != None: annotation = Annotation.objects.get(id=annotation_id) return HttpResponse(json.dumps(to_dict(annotation))) else: # annotation_id not specified # get all annotations within interval form = IntervalForm(request.GET) if not form.is_valid(): return HttpResponseBadRequest(get_json_error(dict( form.errors))) start = form.cleaned_data['start'] end = form.cleaned_data['end'] if start >= end: return HttpResponseBadRequest( get_json_error('invalid interval requested')) # filter by user annotations = Annotation.objects.filter(user=owner) annotations = annotations.filter(end__gte=start) annotations = annotations.filter(start__lte=end) result = [to_dict(annotation) for annotation in annotations] return HttpResponse(json.dumps(result)) elif request.method == "POST": # print "In here..." username = request.POST.get('username') annotation = None if annotation_id != None: annotation = Annotation.objects.get(id=annotation_id) in_pairs = json.loads(request.POST.get('pairs')) pairs = [] for in_pair in in_pairs: # print in_pair try: pair = SensorChannelPair.objects.get( sensor=in_pair['sensor']['id'], channel=in_pair['channel']['id']) except: return HttpResponseBadRequest(get_json_error("invalid pair")) pairs.append(pair) if len(pairs) == 0: return HttpResponseBadRequest( get_json_error("no pairs for annotation")) form = AnnotationForm(request.POST, instance=annotation) if not form.is_valid(): return HttpResponseBadRequest(get_json_error(dict(form.errors))) # print "Now in here." annotation = form.save(commit=False) annotation.user = owner annotation.save() annotation.pairs = pairs annotation.save() return HttpResponse(get_json_success(annotation.id)) elif request.method == "DELETE": annotation = Annotation.objects.get(id=annotation_id) if annotation.user == owner: annotation_id = annotation.id annotation.delete() return HttpResponse(get_json_success(annotation_id)) return HttpResponseForbidden(get_json_error("ACCESS_DENIED")) else: return HttpResponseBadRequest( get_json_error("NOT_GET_POST_OR_DELETE_REQUEST"))
def metering_point_view(request, metering_point_id=None): #log_request('metering_point_view %s'%(str(metering_point_id)), request) if request.method == "GET": if metering_point_id != None: metering_point = MeteringPoint.objects.get(id=metering_point_id) return HttpResponse(json.dumps(to_dict(metering_point))) else: user = request.GET.get('user', request.user.id) metering_points = MeteringPoint.objects.filter(user=user) return HttpResponse(json.dumps([x.id for x in metering_points])) elif request.method == "POST": user = request.user.id if user != None: metering_point_name = request.POST.get('meteringPointName', None) metering_point_description = request.POST.get( 'meteringPointDescription', None) metering_point_meter = request.POST.get('meter', None) if Meter.objects.filter(mac=metering_point_meter).count() > 0: metering_point_meter = Meter.objects.get( mac=metering_point_meter) else: metering_point_meter = None metering_points = MeteringPoint.objects.filter(user=user) metering_point = None if metering_point_id != None: if metering_points.filter(id=metering_point_id).count() > 0: metering_point = metering_points.get(id=metering_point_id) metering_point.name = metering_point_name metering_point.description = metering_point_description metering_point.meter = metering_point_meter else: return HttpResponseNotFound( djutils.get_json_error("NO_SUCH_METERING_POINT")) else: try: metering_point = MeteringPoint( name=metering_point_name, description=metering_point_description, sensor=metering_point_meter, user=request.user) except: return HttpResponseBadRequest( djutils.get_json_error('BAD_ARGS')) metering_point.save() return HttpResponse(djutils.get_json_success(metering_point.id)) return HttpResponseNotFound(djutils.get_json_error("NO_SUCH_USER")) elif request.method == "DELETE": if MeteringPoint.objects.filter(id=metering_point_id).count() > 0: metering_point = MeteringPoint.objects.get(id=metering_point_id) if metering_point.id == request.user.id: metering_point_id = metering_point.id metering_point.delete() return HttpResponse( djutils.get_json_success(metering_point_id)) return HttpResponse(djutils.get_json_error("ACCESS_DENIED"), status=403) return HttpResponseNotFound( djutils.get_json_error("NO_SUCH_METERING_POINT")) return HttpResponseBadRequest( djutils.get_json_error("NOT_GET_POST_OR_DELETE_REQUEST"))
def data_view(request, sensor_id=None, channel_name=None): if request.method == 'GET': # Get sensor and channel sensor = get_object_or_404(Sensor, id=sensor_id) try: channel = sensor.channels.get(name=channel_name) except Channel.DoesNotExist: return HttpResponseNotFound( "This sensor does not appear to contain that channel.") # Check user has permission if djutils.get_requested_user(request) != sensor.user: return HttpResponse( "Attempted to edit another user's sensor. Forbidden.", status=403) # check the interval form form = SampledIntervalForm(request.GET) if not form.is_valid(): return HttpResponseBadRequest( djutils.get_json_error(dict(form.errors))) requested_interval = form.cleaned_data['sampling_interval'] start = form.cleaned_data['start'] end = form.cleaned_data['end'] if start >= end: return HttpResponseBadRequest( djutils.get_json_error('invalid interval requested')) # TODO: using 'power' here as an argument is a hack, it should be fixed reading_list = sdutils.filter_according_to_interval( sensor, channel, start, end, requested_interval, 'generic') result = {} result['data'] = [{ 't': 1000 * mktime(x.timestamp.timetuple()), 'value': x.value } for x in reading_list] if len(result['data']) == 0: #raise SensorReading.DoesNotExist('no sensor readings') result['max_datetime'] = 0 result['min_datetime'] = 0 return HttpResponse(json.dumps(result)) min_datetime = SensorReading.objects.filter( sensor=sensor, channel=channel).aggregate(Min('timestamp'))['timestamp__min'] min_datetime = min_datetime.strftime(djutils.DATE_FMTS[0]) result['min_datetime'] = min_datetime max_datetime = SensorReading.objects.filter( sensor=sensor, channel=channel).aggregate(Max('timestamp'))['timestamp__max'] max_datetime = max_datetime.strftime(djutils.DATE_FMTS[0]) result['max_datetime'] = max_datetime return HttpResponse(json.dumps(result)) elif request.method == 'POST': # TODO: this could be made more clean, using a multi-part post.. # Check inputs are present and deserialisable try: data = json.loads(request.POST['data']) except KeyError: return HttpResponseBadRequest("The data is missing.") except TypeError: return HttpResponseBadRequest( "The data is not a well formed JSON string.") # Get sensor and channel sensor = get_object_or_404(Sensor, id=sensor_id) try: channel = sensor.channels.get(name=channel_name) except Channel.DoesNotExist: return HttpResponseNotFound( "This sensor does not appear to contain that channel.") # Check user has permission if djutils.get_requested_user(request) != sensor.user: return HttpResponse( "Attempted to edit another user's sensor. Forbidden.", status=403) # Add data - checking validity newCount = 0 with commit_on_success(): if type(data) != list: return HttpResponseBadRequest( "data_view requires a list of data points.") for datum in data: try: timestamp = datetime.strptime(str(datum['timestamp']), JS_FMT) value = float(datum['value']) except KeyError: logger.error('error in data posted to sd_store') return HttpResponseBadRequest( "data_view requires data points to have a 'timestamp' and 'value' key." ) except ValueError: logger.error( 'error in data posted to sd_store (timestamp formatting?)' ) return HttpResponseBadRequest( "Timestamps must be formatted:" + JS_FMT + ', and values must be floats.') reading, created = SensorReading.objects.get_or_create( sensor=sensor, channel=channel, timestamp=timestamp, defaults={'value': value}) if not created: reading.value = value reading.save() if created: newCount += 1 return HttpResponse(str(newCount), status=200) else: return HttpResponseNotAllowed(['GET', 'POST'])