347 lines
14 KiB
HTML
347 lines
14 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://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
|
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
|
|
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" crossorigin="anonymous"></script>
|
|
</head>
|
|
<body class="py-4">
|
|
|
|
<!-- START MENU -->
|
|
|
|
<nav class="navbar navbar-expand-sm navbar-dark bg-primary">
|
|
|
|
<a class="navbar-brand" href="/index.htm">Beer Gravity Monitor</a>
|
|
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation">
|
|
<span class="navbar-toggler-icon"></span>
|
|
</button>
|
|
|
|
<div class="collapse navbar-collapse" id="navbar">
|
|
<ul class="navbar-nav mr-auto">
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="/index.htm">Home <span class="sr-only">(current)</span></a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="/device.htm">Device</a>
|
|
</li>
|
|
<li class="nav-item active">
|
|
<a class="nav-link" href="/config.htm">Configuration</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>
|
|
</nav>
|
|
|
|
<!-- START MAIN INDEX -->
|
|
|
|
<div class="container">
|
|
|
|
<hr class="my-2">
|
|
|
|
<div class="alert alert-success alert-dismissible fade hide show d-none" role="alert" id="alert">
|
|
<div id="alert-msg">...</div>
|
|
<button type="button" id="alert-btn" class="close" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
|
|
<script type="text/javascript">
|
|
function showError( msg ) {
|
|
$('.alert').removeClass('alert-success').addClass('alert-danger').removeClass('d-none').addClass('show')
|
|
$('#alert-msg').text( msg );
|
|
}
|
|
|
|
function showSuccess( msg ) {
|
|
$('.alert').addClass('alert-success').removeClass('alert-danger').removeClass('d-none').addClass('show')
|
|
$('#alert-msg').text( msg );
|
|
}
|
|
|
|
$("#alert-btn").click(function(e){
|
|
$('.alert').addClass('d-none').removeClass('show')
|
|
});
|
|
</script>
|
|
|
|
<div class="accordion" id="accordion">
|
|
|
|
<div class="card">
|
|
<div class="card-header" id="headingOne">
|
|
<h2 class="mb-0">
|
|
<button class="btn btn-link btn-block text-left" type="button" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
|
|
Device settings
|
|
</button>
|
|
</h2>
|
|
</div>
|
|
<div id="collapseOne" class="collapse show" aria-labelledby="headingOne" data-parent="#accordion">
|
|
<div class="card-body">
|
|
<form action="/api/config/device" method="post">
|
|
<input type="text" name="id" id="id1" hidden>
|
|
<div class="form-group row">
|
|
<label for="mdns" class="col-sm-4 col-form-label">Device name:</label>
|
|
<div class="col-sm-8">
|
|
<input type="text" maxlength="12" class="form-control" name="mdns" id="mdns">
|
|
</div>
|
|
</div>
|
|
<fieldset class="form-group row">
|
|
<legend class="col-form-label col-sm-4 float-sm-left pt-0">Temperature Format:</legend>
|
|
<div class="col-sm-8">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="radio" name="temp-format" id="temp-format-c" value="C" checked>
|
|
<label class="form-check-label" for="temp-format-c">
|
|
Celsius
|
|
</label>
|
|
</div>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="radio" name="temp-format" id="temp-format-f" value="F">
|
|
<label class="form-check-label" for="temp-format-f">
|
|
Farenheight
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</fieldset>
|
|
<div class="form-group row">
|
|
<label for="sleep-interval" class="col-sm-4 col-form-label">Interval (seconds):</label>
|
|
<div class="col-sm-4">
|
|
<input type="number" min="10" max="10000" class="form-control" name="sleep-interval" id="sleep-interval">
|
|
</div>
|
|
<label for="sleep-interval" class="col-sm-4 col-form-label" id="sleep-interval-info"></label>
|
|
</div>
|
|
<div class="form-group row">
|
|
<div class="col-sm-8 offset-sm-4">
|
|
<button type="submit" class="btn btn-primary" id="device-btn">Save</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
|
|
<div class="form-group row">
|
|
<label for="calibrate-btn" class="col-sm-4 col-form-label">Current calibration values:</label>
|
|
<label for="calibrate-btn" class="col-sm-4 col-form-label" id="gyro-calibration-data">Loading...</label>
|
|
<label for="gyro-calibration-data" class="col-sm-4 col-form-label" id="angle">Loading...</label>
|
|
<div class="col-sm-8 offset-sm-4">
|
|
<button type="button" class="btn btn-warning" id="calibrate-btn">Calibrate device</button>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-header" id="headingTwo">
|
|
<h2 class="mb-0">
|
|
<button class="btn btn-link btn-block text-left collapsed" type="button" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
|
|
Push settings
|
|
</button>
|
|
</h2>
|
|
</div>
|
|
<div id="collapseTwo" class="collapse" aria-labelledby="headingTwo" data-parent="#accordion">
|
|
<div class="card-body">
|
|
<form action="/api/config/push" method="post">
|
|
<input type="text" name="id" id="id2" hidden>
|
|
<div class="form-group row">
|
|
<label for="http-push" class="col-sm-4 col-form-label">Http URL 1:</label>
|
|
<div class="col-sm-8">
|
|
<input type="url" maxlength="90" class="form-control" name="http-push" id="http-push">
|
|
</div>
|
|
</div>
|
|
<div class="form-group row">
|
|
<label for="http-push2" class="col-sm-4 col-form-label">Http URL 2:</label>
|
|
<div class="col-sm-8">
|
|
<input type="url" maxlength="90" class="form-control" name="http-push2" id="http-push2">
|
|
</div>
|
|
</div>
|
|
<div class="form-group row">
|
|
<label for="inputBrewfatherPush" class="col-sm-4 col-form-label">Brewfather URL:</label>
|
|
<div class="col-sm-8">
|
|
<input type="url" maxlength="90" class="form-control" name="brewfather-push" id="brewfather-push">
|
|
</div>
|
|
</div>
|
|
<div class="form-group row">
|
|
<div class="col-sm-8 offset-sm-4">
|
|
<button type="submit" class="btn btn-primary" id="push-btn">Save</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-header" id="headingThree">
|
|
<h2 class="mb-0">
|
|
<button class="btn btn-link btn-block text-left collapsed" type="button" data-toggle="collapse" data-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
|
|
Gravity
|
|
</button>
|
|
</h2>
|
|
</div>
|
|
<div id="collapseThree" class="collapse" aria-labelledby="headingThree" data-parent="#accordion">
|
|
<div class="card-body">
|
|
<form action="/api/config/gravity" method="post">
|
|
<input type="text" name="id" id="id3" hidden>
|
|
<div class="form-group row">
|
|
<label for="gravity-formula" class="col-sm-4 col-form-label">Formula</label>
|
|
<div class="col-sm-8">
|
|
<input type="text" maxlength="200" class="form-control" name="gravity-formula" id="gravity-formula">
|
|
</div>
|
|
</div>
|
|
<label for="gravity-formula"" class="col-sm-8 offset-sm-4 col-form-label" id="gravity">Loading...</label>
|
|
<div class="form-group row">
|
|
<div class="col-sm-8 offset-sm-4">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" name="gravity-temp-adjustment" id="gravity-temp-adjustment">
|
|
<label class="form-check-label" for="gravity-temp-adjustment">
|
|
Temperature adjust gravity
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="form-group row">
|
|
<div class="col-sm-8 offset-sm-4">
|
|
<button type="submit" class="btn btn-primary" id="gravity-btn">Save</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-header" id="headingFour">
|
|
<h2 class="mb-0">
|
|
<button class="btn btn-link btn-block text-left collapsed" type="button" data-toggle="collapse" data-target="#collapseFour" aria-expanded="false" aria-controls="collapseFour">
|
|
Hardware settings
|
|
</button>
|
|
</h2>
|
|
</div>
|
|
<div id="collapseFour" class="collapse" aria-labelledby="headingFour" data-parent="#accordion">
|
|
<div class="card-body">
|
|
<form action="/api/config/hardware" method="post">
|
|
<input type="text" name="id" id="id4" hidden>
|
|
<div class="form-group row">
|
|
<label for="voltage-factor" class="col-sm-4 col-form-label">Voltage factor:</label>
|
|
<div class="col-sm-4">
|
|
<input type="number" step=".01" class="form-control" name="voltage-factor" id="voltage-factor">
|
|
</div>
|
|
<label for="voltage-factor" class="col-sm-4 col-form-label" id="battery">Loading...</label>
|
|
</div>
|
|
<div class="form-group row">
|
|
<label for="temp-adjustment-value" class="col-sm-4 col-form-label">Temp Sensor Adj:</label>
|
|
<div class="col-sm-8">
|
|
<input type="number" step=".1" class="form-control" name="temp-adjustment-value" id="temp-adjustment-value">
|
|
</div>
|
|
</div>
|
|
<div class="form-group row">
|
|
<label for="ota-url" class="col-sm-4 col-form-label">OTA base URL:</label>
|
|
<div class="col-sm-8">
|
|
<input type="url" maxlength="90" class="form-control" name="ota-url" id="ota-url">
|
|
</div>
|
|
</div>
|
|
<div class="form-group row">
|
|
<div class="col-sm-8 offset-sm-4">
|
|
<button type="submit" class="btn btn-primary" id="hardware-btn">Save</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<hr class="my-4">
|
|
</div>
|
|
|
|
<script type="text/javascript">
|
|
window.onload = getConfig;
|
|
|
|
setButtonDisabled( true );
|
|
|
|
// Opens the targetet according (if URL has #collapseOne to #collapseFour)
|
|
$(document).ready(function () {
|
|
if(location.hash != null && location.hash != ""){
|
|
$('.collapse').removeClass('in');
|
|
$(location.hash + '.collapse').collapse('show');
|
|
}
|
|
});
|
|
|
|
// Trigger the calibration
|
|
$("#calibrate-btn").click(function(e){
|
|
console.log( "Calibrating..." );
|
|
$.ajax( {
|
|
type: "POST",
|
|
url: "/api/calibrate",
|
|
data: { id: $("#id1").val() },
|
|
success: function(result) { showSuccess('Calibration of device was completed successfully.'); getConfig(); },
|
|
error: function(result) { showError('Unable to calibrate device.'); }
|
|
} );
|
|
});
|
|
|
|
function updateSleepInfo() {
|
|
var i = $("#sleep-interval").val()
|
|
$("#sleep-interval-info").text( Math.floor(i/60) + " m " + (i%60) + " s" )
|
|
}
|
|
|
|
// Trigger the calibration
|
|
$("#sleep-interval").keyup(updateSleepInfo);
|
|
|
|
function setButtonDisabled( b ) {
|
|
$("#device-btn").prop("disabled", b);
|
|
$("#calibrate-btn").prop("disabled", b);
|
|
$("#push-btn").prop("disabled", b);
|
|
$("#gravity-btn").prop("disabled", b);
|
|
$("#hardware-btn").prop("disabled", b);
|
|
}
|
|
|
|
// Get the configuration values from the API
|
|
function getConfig() {
|
|
setButtonDisabled( true );
|
|
|
|
var url = "/api/config";
|
|
//var url = "/test/config.json";
|
|
$('#spinner').show();
|
|
$.getJSON(url, function (cfg) {
|
|
console.log( cfg );
|
|
$("#id1").val(cfg["id"]);
|
|
$("#id2").val(cfg["id"]);
|
|
$("#id3").val(cfg["id"]);
|
|
$("#id4").val(cfg["id"]);
|
|
$("#mdns").val(cfg["mdns"]);
|
|
if( cfg["temp-format"] == "C" )
|
|
$("#temp-format-c").click();
|
|
else
|
|
$("#temp-format-f").click();
|
|
$("#ota-url").val(cfg["ota-url"]);
|
|
$("#http-push").val(cfg["http-push"]);
|
|
$("#http-push2").val(cfg["http-push2"]);
|
|
$("#brewfather-push").val(cfg["brewfather-push"]);
|
|
$("#sleep-interval").val(cfg["sleep-interval"]);
|
|
$("#voltage-factor").val(cfg["voltage-factor"]);
|
|
$("#gravity-formula").val(cfg["gravity-formula"]);
|
|
$("#temp-adjustment-value").val(cfg["temp-adjustment-value"]);
|
|
$("#gravity-temp-adjustment").prop( "checked", cfg["gravity-temp-adjustment"] );
|
|
$("#gyro-calibration-data").text( cfg["gyro-calibration-data"]["ax"] + "," + cfg["gyro-calibration-data"]["ay"] + "," + cfg["gyro-calibration-data"]["az"] + "," + cfg["gyro-calibration-data"]["gx"] + "," + cfg["gyro-calibration-data"]["gy"] + "," + cfg["gyro-calibration-data"]["gz"] );
|
|
$("#battery").text(cfg["battery"] + " V");
|
|
$("#angle").text(cfg["angle"]);
|
|
$("#gravity").text(cfg["gravity"] + " SG");
|
|
})
|
|
.fail(function () {
|
|
showError('Unable to get data from the device.');
|
|
})
|
|
.always(function() {
|
|
$('#spinner').hide();
|
|
setButtonDisabled( false );
|
|
updateSleepInfo();
|
|
});
|
|
}
|
|
</script>
|
|
|
|
<!-- START FOOTER -->
|
|
|
|
<div class="container-fluid themed-container bg-primary text-light">(C) Copyright 2021 Magnus Persson</div>
|
|
</body>
|
|
</html> |