52 lines
10 KiB
HTML
52 lines
10 KiB
HTML
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name="description" content=""><title>Beer Gravity Monitor</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous"><script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script><script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script><script src="https://cdn.jsdelivr.net/npm/chart.js"></script><style>.row-margin-05{margin-top:.5em}.row-margin-10{margin-top:1em}</style></head><body class="py-4"><!-- START MENU --><nav class="navbar navbar-expand-lg navbar-dark bg-primary"><div class="container"><a class="navbar-brand" href="/index.htm">Beer Gravity Monitor</a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button><div class="collapse navbar-collapse" id="navbarNav"><ul class="navbar-nav"><li class="nav-item"><a class="nav-link" href="/index.htm">Home</a></li><li class="nav-item"><a class="nav-link" href="/config.htm">Configuration</a></li><li class="nav-item active"><a class="nav-link" href="#"><b>Calibration</b></a></li><li class="nav-item"><a class="nav-link" href="/about.htm">About</a></li></ul></div><div class="spinner-border text-light" id="spinner" role="status"></div></div></nav><!-- START BODY --><div class="container row-margin-10"><div class="alert alert-success alert-dismissible hide fade d-none" role="alert"><div id="alert"></div><button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button></div><script type="text/javascript">function showError(s){$(".alert").removeClass("alert-success").addClass("alert-danger").removeClass("hide").addClass("show").removeClass("d-none"),$("#alert").text(s)}function showSuccess(s){$(".alert").addClass("alert-success").removeClass("alert-danger").removeClass("hide").addClass("show").removeClass("d-none"),$("#alert").text(s)}$("#alert-btn").click(function(s){$(".alert").addClass("hide").removeClass("show").addClass("d-none")})</script><div class="accordion" id="accordion"><div class="accordion-item"><h2 class="accordion-header" id="headingFormula"><button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseFormula" aria-expanded="true" aria-controls="collapseFormula"><b>Formula calculation</b></button></h2><div id="collapseFormula" class="accordion-collapse collapse show" aria-labelledby="headingFormula" data-bs-parent="#accordion"><div class="accordion-body"><form action="/api/formula" method="post"><input type="text" name="gravity-format" id="gravity-format" hidden> <input type="text" name="id" id="id" hidden><div class="row mb-3">Here you can create your gravity formula by entering angles/tilt and the corresponding gravity. These values will be saved for future use. Angles with 0 (zero) will be skipped. The values below will be used to check the formula and if the deviation is more than 1.5SG / 0.38P on any of the provided points then the forumla will be rejected. On the bottom of the page you can see a graph over the entered values + values calcualated by the formula.</div><div class="row"><label class="col-sm-1 col-form-label">#</label> <label class="col-sm-4 col-form-label">Angle/Tilt</label> <label class="col-sm-4 col-form-label" id="gravity-header">Gravity</label></div><div class="row mb-3"><label for="angle1" class="col-sm-1 col-form-label">1.</label><div class="col-sm-4"><input type="number" min="0" max="90" step="0.001" class="form-control" name="a1" id="a1"></div><div class="col-sm-4"><input type="number" min="0" max="26" step="0.0001" class="form-control" name="g1" id="g1"></div></div><div class="row mb-3"><label for="angle2" class="col-sm-1 col-form-label">2.</label><div class="col-sm-4"><input type="number" min="0" max="90" step="0.001" class="form-control" name="a2" id="a2"></div><div class="col-sm-4"><input type="number" min="0" max="26" step="0.0001" class="form-control" name="g2" id="g2"></div></div><div class="row mb-3"><label for="angle3" class="col-sm-1 col-form-label">3.</label><div class="col-sm-4"><input type="number" min="0" max="90" step="0.001" class="form-control" name="a3" id="a3"></div><div class="col-sm-4"><input type="number" min="0" max="26" step="0.0001" class="form-control" name="g3" id="g3"></div></div><div class="row mb-3"><label for="angle4" class="col-sm-1 col-form-label">4.</label><div class="col-sm-4"><input type="number" min="0" max="90" step="0.001" class="form-control" name="a4" id="a4"></div><div class="col-sm-4"><input type="number" min="0" max="26" step="0.0001" class="form-control" name="g4" id="g4"></div></div><div class="row mb-3"><label for="angle5" class="col-sm-1 col-form-label">5.</label><div class="col-sm-4"><input type="number" min="0" max="90" step="0.001" class="form-control" name="a5" id="a5"></div><div class="col-sm-4"><input type="number" min="0" max="26" step="0.0001" class="form-control" name="g5" id="g5"></div></div><div class="row mb-3"><div class="col-sm-8 offset-sm-1"><button type="submit" class="btn btn-primary" id="calculate-btn">Save & Calculate</button></div></div><hr class="my-2"><div class="row"><label for="calculate-btn" class="col-sm-2 col-form-label">Current angle:</label> <label for="calculate-btn" class="col-sm-2 col-form-label" id="angle"></label></div><div class="row"><label for="calculate-btn" class="col-sm-2 col-form-label">Formula:</label> <label for="calculate-btn" class="col-sm-8 col-form-label" id="formula">Loading...</label></div></form></div></div></div><div class="accordion-item"><h2 class="accordion-header" id="headingGraph"><button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseGraph" aria-expanded="false" aria-controls="collapseGraph"><b>Formula graph</b></button></h2><div id="collapseGraph" class="accordion-collapse collapse" aria-labelledby="headingGraph" data-bs-parent="#accordion"><div class="accordion-body"><canvas id="gravityChart"></canvas></div></div></div></div></div><script type="text/javascript">var chartDataForm = [];
|
|
var chartDataCalc = [];
|
|
|
|
const dataSetChart = {
|
|
datasets: [{
|
|
label: 'Raw data',
|
|
borderColor: 'blue',
|
|
backgroundColor: 'blue',
|
|
data: chartDataForm
|
|
}, {
|
|
label: 'Calculated',
|
|
borderColor: 'green',
|
|
backgroundColor: 'green',
|
|
data: chartDataCalc
|
|
}]
|
|
}
|
|
|
|
const configChart = {
|
|
type: 'line',
|
|
data: dataSetChart,
|
|
options: {
|
|
responsive: true,
|
|
interaction: {
|
|
intersect: false,
|
|
},
|
|
scales: {
|
|
x: {
|
|
display: true,
|
|
type: 'linear',
|
|
grace: '5%',
|
|
title: {
|
|
display: true,
|
|
text: 'Angle/Tilt'
|
|
},
|
|
ticks: {
|
|
crossAlign: 'far'
|
|
},
|
|
suggestedMin: 25
|
|
},
|
|
y: {
|
|
display: true,
|
|
title: {
|
|
display: true,
|
|
text: 'Gravity'
|
|
},
|
|
suggestedMin: 1.000
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
var myChart = 0;</script><script type="text/javascript">function convertToPlato(a){return 259-259/a}function convertToSG(a){return 259/(259-a)}function setAngleDecimal(a){this.value=parseFloat(this.value).toFixed(2),populateChart()}function setGravityDecimal(a){isPlato()?this.value=parseFloat(this.value).toFixed(1):this.value=parseFloat(this.value).toFixed(4),populateChart()}function populateChartForm(a,t){0!=a&&chartDataForm.push({x:parseFloat(a),y:parseFloat(t)}),chartDataForm.sort(function(a,t){return a.x-t.x})}function populateChartCalc(a,t){chartDataCalc.push({x:parseFloat(a),y:parseFloat(t)})}function isPlato(){return"P"==$("#gravity-format").text()}function populateChart(){for(chartDataCalc.length=0,i=25;i<80;i+=5){var formula=$("#formula").text(),angle=i.toString();formula=formula.replaceAll("tilt^3",angle+"*"+angle+"*"+angle),formula=formula.replaceAll("tilt^2",angle+"*"+angle),formula=formula.replaceAll("tilt",angle);var g=eval(formula);isPlato()&&(g=convertToPlato(g)),populateChartCalc(i,g)}chartDataForm.length=0,populateChartForm($("#a1").val(),$("#g1").val()),populateChartForm($("#a2").val(),$("#g2").val()),populateChartForm($("#a3").val(),$("#g3").val()),populateChartForm($("#a4").val(),$("#g4").val()),populateChartForm($("#a5").val(),$("#g5").val()),myChart&&myChart.destroy(),myChart=new Chart(document.getElementById("gravityChart"),configChart)}function setButtonDisabled(a){$("#calculate-btn").prop("disabled",a)}function getConfig(){setButtonDisabled(!0);var a="/api/formula";$("#spinner").show(),$.getJSON(a,function(a){console.log(a),$("#id").val(a.id),$("#angle").text(a.angle),$("#formula").text(a["gravity-formula"]),$("#gravity-format").text(a["gravity-format"]),isPlato()?($("#gravity-header").text("Gravity (Plato):"),$("#g1").val(parseFloat(a.g1).toFixed(1)),$("#g2").val(parseFloat(a.g2).toFixed(1)),$("#g3").val(parseFloat(a.g3).toFixed(1)),$("#g4").val(parseFloat(a.g4).toFixed(1)),$("#g5").val(parseFloat(a.g5).toFixed(1))):($("#gravity-header").text("Gravity (SG):"),$("#g1").val(parseFloat(a.g1).toFixed(4)),$("#g2").val(parseFloat(a.g2).toFixed(4)),$("#g3").val(parseFloat(a.g3).toFixed(4)),$("#g4").val(parseFloat(a.g4).toFixed(4)),$("#g5").val(parseFloat(a.g5).toFixed(4))),$("#a1").val(parseFloat(a.a1).toFixed(2)),$("#a2").val(parseFloat(a.a2).toFixed(2)),$("#a3").val(parseFloat(a.a3).toFixed(2)),$("#a4").val(parseFloat(a.a4).toFixed(2)),$("#a5").val(parseFloat(a.a5).toFixed(2)),""!=a.error&&showError(a.error),populateChart()}).fail(function(){showError("Unable to get data from the device.")}).always(function(){$("#spinner").hide(),setButtonDisabled(!1)})}g1.onchange=setGravityDecimal,g2.onchange=setGravityDecimal,g3.onchange=setGravityDecimal,g4.onchange=setGravityDecimal,g5.onchange=setGravityDecimal,a1.onchange=setAngleDecimal,a2.onchange=setAngleDecimal,a3.onchange=setAngleDecimal,a4.onchange=setAngleDecimal,a5.onchange=setAngleDecimal,window.onload=getConfig,setButtonDisabled(!0)</script><!-- START FOOTER --><div class="container themed-container bg-primary text-light row-margin-10">(C) Copyright 2021-22 Magnus Persson</div></body></html> |