Example #1
0
def gravity_manage(request, sensor_id):
    # TODO - Add user permissioning
    # if not request.user.has_perm('app.edit_device'):
    #     messages.error(request, 'Your account is not permissioned to edit devices. Please contact an admin')
    #     return redirect("/")

    try:
        sensor = GravitySensor.objects.get(id=sensor_id)
    except ObjectDoesNotExist:
        messages.error(request,
                       u'Unable to load sensor with ID {}'.format(sensor_id))
        return redirect('gravity_log_list')

    context = {'active_device': sensor}

    if sensor.sensor_type == GravitySensor.SENSOR_ISPINDEL:
        # I am sure there is an easier way to do this, I just can't think of it at the moment
        initial = {
            'a': sensor.ispindel_configuration.third_degree_coefficient,
            'b': sensor.ispindel_configuration.second_degree_coefficient,
            'c': sensor.ispindel_configuration.first_degree_coefficient,
            'd': sensor.ispindel_configuration.constant_term,
        }
        ispindel_coefficient_form = forms.IspindelCoefficientForm(
            initial=initial)
        context['ispindel_coefficient_form'] = ispindel_coefficient_form

        calibration_points = IspindelGravityCalibrationPoint.objects.filter(
            sensor=sensor.ispindel_configuration).order_by('angle')
        context['ispindel_calibration_points'] = calibration_points
        ispindel_calibration_form = forms.IspindelCalibrationPointForm(
            initial={'sensor': sensor.ispindel_configuration})
        context['ispindel_calibration_form'] = ispindel_calibration_form

    if sensor.sensor_type == GravitySensor.SENSOR_TILT:
        # I am sure there is an easier way to do this, I just can't think of it at the moment
        initial = {
            'b': sensor.tilt_configuration.grav_second_degree_coefficient,
            'c': sensor.tilt_configuration.grav_first_degree_coefficient,
            'd': sensor.tilt_configuration.grav_constant_term,
        }
        tilt_coefficient_form = forms.TiltCoefficientForm(initial=initial)
        context['tilt_coefficient_form'] = tilt_coefficient_form

        calibration_points = TiltGravityCalibrationPoint.objects.filter(
            sensor=sensor.tilt_configuration).order_by('tilt_measured_gravity')
        context['tilt_calibration_points'] = calibration_points
        tilt_calibration_form = forms.TiltGravityCalibrationPointForm(
            initial={'sensor': sensor.tilt_configuration})
        context['tilt_calibration_form'] = tilt_calibration_form

    return render(request,
                  template_name='gravity/gravity_manage.html',
                  context=context)
def gravity_ispindel_add_calibration_point(request, sensor_id):
    # TODO - Add user permissioning
    # if not request.user.has_perm('app.edit_device'):
    #     messages.error(request, 'Your account is not permissioned to edit devices. Please contact an admin')
    #     return redirect("/")

    try:
        sensor = GravitySensor.objects.get(id=sensor_id)
    except:
        messages.error(request,
                       u'Unable to load sensor with ID {}'.format(sensor_id))
        return redirect('gravity_log_list')

    if sensor.sensor_type != GravitySensor.SENSOR_ISPINDEL:
        messages.error(
            request,
            u'Sensor {} is not an iSpindel and cannot be configured in this way'
            .format(sensor_id))
        return redirect('gravity_log_list')

    if request.POST:
        ispindel_calibration_point_form = forms.IspindelCalibrationPointForm(
            request.POST)
        if ispindel_calibration_point_form.is_valid():
            ispindel_calibration_point_form.save()
            messages.success(request, u"Calibration point added")

            if sensor.ispindel_configuration.coefficients_up_to_date:
                # If we're changing any coefficients since the calibration script was last run, clear the 'calibrated'
                # flag so we know.
                messages.warning(
                    request,
                    u"New calibration points have been added since the coefficients were last "
                    u"calculated - please re-run the coefficient calculation script to update "
                    u"the specific gravity equation.")
                sensor.ispindel_configuration.coefficients_up_to_date = False
                sensor.ispindel_configuration.save()

        else:
            messages.error(request, u"Invalid calibration point provided")
    else:
        messages.error(request, u"No calibration point provided")

    return redirect("gravity_manage", sensor_id=sensor_id)
def gravity_ispindel_guided_calibration(request, sensor_id, step):
    # TODO - Add user permissioning
    # if not request.user.has_perm('app.edit_device'):
    #     messages.error(request, 'Your account is not permissioned to edit devices. Please contact an admin')
    #     return redirect("/")

    try:
        sensor = GravitySensor.objects.get(id=sensor_id)
    except:
        messages.error(request,
                       u'Unable to load sensor with ID {}'.format(sensor_id))
        return redirect('gravity_log_list')

    if sensor.sensor_type != GravitySensor.SENSOR_ISPINDEL:
        messages.error(
            request,
            u"Sensor {} is not an iSpindel sensor".format(sensor.name))
        return redirect('gravity_log_list')

    # Let's coerce step to an integer so we can do math on it
    step = int(step)

    # Before we do anything, see if we were passed data. If we were, process it.
    if "sensor" in request.POST:
        ispindel_calibration_point_form = forms.IspindelCalibrationPointForm(
            request.POST)
        if ispindel_calibration_point_form.is_valid():
            try:
                # If a point exists with the exact same specific gravity that we just entered, delete it.
                # This is specifically to prevent the user from accidentally running this calibration twice.
                point_to_delete = IspindelGravityCalibrationPoint.objects.get(
                    gravity=ispindel_calibration_point_form.
                    cleaned_data['gravity'],
                    sensor=sensor.ispindel_configuration)
                point_to_delete.delete()
            except:
                # No point existed. We're good.
                pass

            ispindel_calibration_point_form.save()
            messages.success(request, u"Calibration point added")

            if sensor.ispindel_configuration.coefficients_up_to_date:
                sensor.ispindel_configuration.coefficients_up_to_date = False
                sensor.ispindel_configuration.save()

        else:
            messages.error(
                request,
                u"Invalid calibration point provided - recheck the angle you entered & try again"
            )
            return redirect("gravity_ispindel_guided_calibration",
                            sensor_id=sensor_id,
                            step=(step - 1))
    else:
        # If we hit this, the user isn't submitting data. The user is allowed to skip steps - it just isn't recommended.
        pass

    # Alrighty. Let's calculate where we should land on each step of the calibration.

    # Water additions by step & sugar additions by step are both the amount of water/sugar being added in each step
    # in grams.
    water_additions_by_step = [2750, 125, 125, 250, 250, 250, 250, 250]
    sugar_additions_by_step = [0, 150, 150, 300, 300, 300, 300, 300]

    # Now let's translate that into data, organized by step (Note - step number is one-off from the 'step' parameter)

    step_data = []
    for i in range(len(water_additions_by_step)):
        this_step = {'step': (i + 1)}
        this_step['water_addition'] = water_additions_by_step[i]
        this_step['sugar_addition'] = sugar_additions_by_step[i]

        this_step['cumulative_water'] = this_step['water_addition']
        this_step['cumulative_sugar'] = this_step['sugar_addition']
        if i > 0:
            this_step['cumulative_water'] += step_data[i -
                                                       1]['cumulative_water']
            this_step['cumulative_sugar'] += step_data[i -
                                                       1]['cumulative_sugar']

        this_step['plato'] = 1.0 * this_step['cumulative_sugar'] / (
            this_step['cumulative_sugar'] +
            this_step['cumulative_water']) * 100
        this_step['specific_gravity'] = round(
            decimal.Decimal(1 + this_step['plato'] /
                            (258.6 - (227.1 * (this_step['plato'] / 258.2)))),
            4)
        this_step['plato'] = round(decimal.Decimal(this_step['plato']),
                                   2)  # Make it pretty to look at

        try:
            point_with_grav = IspindelGravityCalibrationPoint.objects.get(
                gravity=this_step['specific_gravity'],
                sensor=sensor.ispindel_configuration)
            this_step['angle'] = point_with_grav.angle
        except:
            this_step['angle'] = ""

        step_data.append(this_step)

    # Now we're ready to proceed. Let's build the context & then determine what template to output to the user
    context = {
        'all_steps_data': step_data,
        'on_step': step,
        'next_step': step + 1,
        'active_device': sensor
    }

    if step == 0:
        # Step 0 just lays out the basic instructions. We do want to collect existing points (if any) so we can warn
        # the user, however.
        existing_points = IspindelGravityCalibrationPoint.objects.filter(
            sensor=sensor.ispindel_configuration)
        context['existing_points'] = existing_points
        return render(
            request,
            template_name='gravity/gravity_ispindel_calibrate_start.html',
            context=context)
    elif step <= len(water_additions_by_step):
        ispindel_calibration_form = forms.IspindelCalibrationPointForm(
            initial={
                'sensor': sensor.ispindel_configuration,
                'gravity': step_data[step - 1]['specific_gravity']
            })
        context['ispindel_calibration_form'] = ispindel_calibration_form
        context['this_step_data'] = step_data[step - 1]
        return render(
            request,
            template_name='gravity/gravity_ispindel_calibrate_step.html',
            context=context)
    else:
        # Last step is just a message.
        return render(
            request,
            template_name='gravity/gravity_ispindel_calibrate_end.html',
            context=context)
Example #4
0
def gravity_manage(request, sensor_id):
    # TODO - Add user permissioning
    # if not request.user.has_perm('app.edit_device'):
    #     messages.error(request, 'Your account is not permissioned to edit devices. Please contact an admin')
    #     return redirect("/")

    try:
        sensor = GravitySensor.objects.get(id=sensor_id)
    except ObjectDoesNotExist:
        messages.error(request,
                       u'Unable to load sensor with ID {}'.format(sensor_id))
        return redirect('gravity_log_list')

    context = {'active_device': sensor}

    if sensor.sensor_type == GravitySensor.SENSOR_ISPINDEL:
        # I am sure there is an easier way to do this, I just can't think of it at the moment
        try:
            initial = {
                'a': sensor.ispindel_configuration.third_degree_coefficient,
                'b': sensor.ispindel_configuration.second_degree_coefficient,
                'c': sensor.ispindel_configuration.first_degree_coefficient,
                'd': sensor.ispindel_configuration.constant_term,
                't': sensor.ispindel_configuration.temperature_correction,
            }
        except ObjectDoesNotExist:
            # The sensor is in an inconsistent state. Delete it.
            messages.error(
                request,
                f"The gravity sensor {sensor.name} had incomplete configuration and was deleted"
            )
            sensor.delete()
            return redirect("siteroot")

        ispindel_coefficient_form = forms.IspindelCoefficientForm(
            initial=initial)
        context['ispindel_coefficient_form'] = ispindel_coefficient_form

        calibration_points = IspindelGravityCalibrationPoint.objects.filter(
            sensor=sensor.ispindel_configuration).order_by('angle')
        context['ispindel_calibration_points'] = calibration_points
        ispindel_calibration_form = forms.IspindelCalibrationPointForm(
            initial={'sensor': sensor.ispindel_configuration})
        context['ispindel_calibration_form'] = ispindel_calibration_form
        #context['temp_display_format'] = config.DATE_TIME_FORMAT_DISPLAY

        return render(request,
                      template_name='gravity/gravity_manage_ispindel.html',
                      context=context)

    elif sensor.sensor_type == GravitySensor.SENSOR_TILT:
        # I am sure there is an easier way to do this, I just can't think of it at the moment
        try:
            initial = {
                'b': sensor.tilt_configuration.grav_second_degree_coefficient,
                'c': sensor.tilt_configuration.grav_first_degree_coefficient,
                'd': sensor.tilt_configuration.grav_constant_term,
            }
        except ObjectDoesNotExist:
            # The sensor is in an inconsistent state. Delete it.
            messages.error(
                request,
                f"The gravity sensor {sensor.name} had incomplete configuration and was deleted"
            )
            sensor.delete()
            return redirect("siteroot")

        tilt_coefficient_form = forms.TiltCoefficientForm(initial=initial)
        context['tilt_coefficient_form'] = tilt_coefficient_form

        calibration_points = TiltGravityCalibrationPoint.objects.filter(
            sensor=sensor.tilt_configuration).order_by('tilt_measured_gravity')
        context['tilt_calibration_points'] = calibration_points
        tilt_calibration_form = forms.TiltGravityCalibrationPointForm(
            initial={'sensor': sensor.tilt_configuration})
        context['tilt_calibration_form'] = tilt_calibration_form

        tilt_extras = sensor.tilt_configuration.load_extras_from_redis()
        context['tilt_extras'] = tilt_extras

        if sensor.tilt_configuration.connection_type == TiltConfiguration.CONNECTION_BRIDGE:
            # For TiltBridges, we want to give the user the info necessary to configure the device to communicate with
            # Fermentrack
            fermentrack_host = request.META['HTTP_HOST']
            context[
                'fermentrack_url'] = f"http://{fermentrack_host}/tiltbridge/"

        return render(request,
                      template_name='gravity/gravity_manage_tilt.html',
                      context=context)
    else:
        return render(request,
                      template_name='gravity/gravity_manage.html',
                      context=context)
Example #5
0
def gravity_manage(request, sensor_id):
    # TODO - Add user permissioning
    # if not request.user.has_perm('app.edit_device'):
    #     messages.error(request, 'Your account is not permissioned to edit devices. Please contact an admin')
    #     return redirect("/")

    try:
        sensor = GravitySensor.objects.get(id=sensor_id)
    except ObjectDoesNotExist:
        messages.error(request,
                       u'Unable to load sensor with ID {}'.format(sensor_id))
        return redirect('gravity_log_list')

    context = {'active_device': sensor}

    if sensor.sensor_type == GravitySensor.SENSOR_ISPINDEL:
        # I am sure there is an easier way to do this, I just can't think of it at the moment
        try:
            initial = {
                'a': sensor.ispindel_configuration.third_degree_coefficient,
                'b': sensor.ispindel_configuration.second_degree_coefficient,
                'c': sensor.ispindel_configuration.first_degree_coefficient,
                'd': sensor.ispindel_configuration.constant_term,
            }
        except ObjectDoesNotExist:
            # The sensor is in an inconsistent state. Delete it.
            messages.error(
                request,
                u"The gravity sensor {} had incomplete configuration and was deleted"
                .format(sensor.name))
            sensor.delete()
            return redirect("siteroot")

        ispindel_coefficient_form = forms.IspindelCoefficientForm(
            initial=initial)
        context['ispindel_coefficient_form'] = ispindel_coefficient_form

        calibration_points = IspindelGravityCalibrationPoint.objects.filter(
            sensor=sensor.ispindel_configuration).order_by('angle')
        context['ispindel_calibration_points'] = calibration_points
        ispindel_calibration_form = forms.IspindelCalibrationPointForm(
            initial={'sensor': sensor.ispindel_configuration})
        context['ispindel_calibration_form'] = ispindel_calibration_form

        return render(request,
                      template_name='gravity/gravity_manage_ispindel.html',
                      context=context)

    elif sensor.sensor_type == GravitySensor.SENSOR_TILT:
        # I am sure there is an easier way to do this, I just can't think of it at the moment
        try:
            initial = {
                'b': sensor.tilt_configuration.grav_second_degree_coefficient,
                'c': sensor.tilt_configuration.grav_first_degree_coefficient,
                'd': sensor.tilt_configuration.grav_constant_term,
            }
        except ObjectDoesNotExist:
            # The sensor is in an inconsistent state. Delete it.
            messages.error(
                request,
                u"The gravity sensor {} had incomplete configuration and was deleted"
                .format(sensor.name))
            sensor.delete()
            return redirect("siteroot")

        tilt_coefficient_form = forms.TiltCoefficientForm(initial=initial)
        context['tilt_coefficient_form'] = tilt_coefficient_form

        calibration_points = TiltGravityCalibrationPoint.objects.filter(
            sensor=sensor.tilt_configuration).order_by('tilt_measured_gravity')
        context['tilt_calibration_points'] = calibration_points
        tilt_calibration_form = forms.TiltGravityCalibrationPointForm(
            initial={'sensor': sensor.tilt_configuration})
        context['tilt_calibration_form'] = tilt_calibration_form

        if sensor.tilt_configuration.connection_type == TiltConfiguration.CONNECTION_BRIDGE:
            # For TiltBridges, we want to give the user the info necessary to configure the device to communicate with
            # Fermentrack
            fermentrack_host = request.META['HTTP_HOST']
            try:
                if ":" in fermentrack_host:
                    fermentrack_host = fermentrack_host[:fermentrack_host.
                                                        find(":")]
                ais = socket.getaddrinfo(fermentrack_host, 0, 0, 0, 0)
                ip_list = [result[-1][0] for result in ais]
                ip_list = list(set(ip_list))
                resolved_address = ip_list[0]
                fermentrack_url = "http://{}/tiltbridge/".format(
                    resolved_address)
            except:
                # For some reason we failed to resolve the IP address of Fermentrack
                fermentrack_url = "<Error - Unable to resolve Fermentrack IP address>"
            context['fermentrack_url'] = fermentrack_url

        return render(request,
                      template_name='gravity/gravity_manage_tilt.html',
                      context=context)
    else:
        return render(request,
                      template_name='gravity/gravity_manage.html',
                      context=context)