Example #1
0
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))
Example #2
0
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))
Example #3
0
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"))
Example #4
0
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)
Example #6
0
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"))
Example #7
0
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))
Example #8
0
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))
Example #9
0
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"))
Example #10
0
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"))
Example #11
0
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"))
Example #12
0
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'])