Added http get option to push
This commit is contained in:
parent
6e9d562977
commit
4cad6f888f
@ -175,7 +175,7 @@
|
||||
<input type="text" name="http-push2-h2" id="http-push2-h2" hidden>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="http-push" class="col-sm-2 col-form-label">Http URL 1:</label>
|
||||
<label for="http-push" class="col-sm-2 col-form-label">HTTP 1 (POST):</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="url" maxlength="120" class="form-control" name="http-push" id="http-push">
|
||||
</div>
|
||||
@ -184,7 +184,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="http-push2" class="col-sm-2 col-form-label">Http URL 2:</label>
|
||||
<label for="http-push2" class="col-sm-2 col-form-label">HTTP 2 (POST):</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="url" maxlength="120" class="form-control" name="http-push2" id="http-push2">
|
||||
</div>
|
||||
@ -193,8 +193,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="my-2">
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="token" class="col-sm-2 col-form-label">Token:</label>
|
||||
<div class="col-sm-4">
|
||||
@ -204,6 +202,22 @@
|
||||
|
||||
<hr class="my-2">
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="http-push3" class="col-sm-2 col-form-label">HTTP 3 (GET):</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="url" maxlength="120" class="form-control" name="http-push3" id="http-push3">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="token2" class="col-sm-2 col-form-label">Token 2:</label>
|
||||
<div class="col-sm-4">
|
||||
<input type="text" maxlength="50" class="form-control" name="token2" id="token2">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="my-2">
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="inputBrewfatherPush" class="col-sm-2 col-form-label">Brewfather URL:</label>
|
||||
<div class="col-sm-10">
|
||||
@ -617,12 +631,14 @@ function checkHeader(input) {
|
||||
else $("#gravity-format-p").click();
|
||||
$("#ota-url").val(cfg["ota-url"]);
|
||||
$("#token").val(cfg["token"]);
|
||||
$("#token2").val(cfg["token2"]);
|
||||
$("#http-push").val(cfg["http-push"]);
|
||||
$("#http-push-h1").val(cfg["http-push-h1"]);
|
||||
$("#http-push-h2").val(cfg["http-push-h2"]);
|
||||
$("#http-push2").val(cfg["http-push2"]);
|
||||
$("#http-push2-h1").val(cfg["http-push2-h1"]);
|
||||
$("#http-push2-h2").val(cfg["http-push2-h2"]);
|
||||
$("#http-push3").val(cfg["http-push3"]);
|
||||
$("#brewfather-push").val(cfg["brewfather-push"]);
|
||||
$("#influxdb2-push").val(cfg["influxdb2-push"]);
|
||||
$("#influxdb2-org").val(cfg["influxdb2-org"]);
|
||||
|
File diff suppressed because one or more lines are too long
@ -74,6 +74,7 @@
|
||||
<input type="text" name="id" id="id" hidden>
|
||||
<input type="text" name="http-1" id="http-1" hidden>
|
||||
<input type="text" name="http-2" id="http-2" hidden>
|
||||
<input type="text" name="http-3" id="http-3" hidden>
|
||||
<!--<input type="text" name="brewfather" id="brewfather" hidden>-->
|
||||
<input type="text" name="influxdb" id="influxdb" hidden>
|
||||
<input type="text" name="mqtt" id="mqtt" hidden>
|
||||
@ -81,8 +82,9 @@
|
||||
<div class="form-group row">
|
||||
<label for="push-target" class="col-sm-2 col-form-label">Push target:</label>
|
||||
<select class="custom-select col-sm-4" required name="push-target" id="push-target">
|
||||
<option value="http-1">HTTP option 1</option>
|
||||
<option value="http-2">HTTP option 2</option>
|
||||
<option value="http-1">HTTP option 1 (post)</option>
|
||||
<option value="http-2">HTTP option 2 (post)</option>
|
||||
<option value="http-3">HTTP option 3 (get)</option>
|
||||
<!--<option value="brewfather">Brewfather</option>-->
|
||||
<option value="influxdb">Influx DB</option>
|
||||
<option value="mqtt">MQTT</option>
|
||||
@ -181,6 +183,7 @@
|
||||
doc = doc.replaceAll("${id}", cfg["id"]);
|
||||
doc = doc.replaceAll("${sleep-interval}", cfg["sleep-interval"]);
|
||||
doc = doc.replaceAll("${token}", cfg["token"]);
|
||||
doc = doc.replaceAll("${token2}", cfg["token2"]);
|
||||
doc = doc.replaceAll("${temp-c}", cfg["temp-c"]);
|
||||
doc = doc.replaceAll("${temp-f}", cfg["temp-f"]);
|
||||
doc = doc.replaceAll("${temp-unit}", cfg["temp-format"]);
|
||||
@ -242,6 +245,7 @@
|
||||
|
||||
$("#http-1").val(cfg["http-1"]);
|
||||
$("#http-2").val(cfg["http-2"]);
|
||||
$("#http-3").val(cfg["http-3"]);
|
||||
//$("#brewfather").val(cfg["brewfather"]);
|
||||
$("#influxdb").val(cfg["influxdb"]);
|
||||
$("#mqtt").val(cfg["mqtt"]);
|
||||
|
@ -1,2 +1,2 @@
|
||||
<!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 rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" 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://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" 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="javascript:history.back()">Back to configuration</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(s){$("#alert").removeClass("alert-success").addClass("alert-danger").removeClass("d-none").addClass("show"),$("#alert-msg").text(s)}function showSuccess(s){$("#alert").addClass("alert-success").removeClass("alert-danger").removeClass("d-none").addClass("show"),$("#alert-msg").text(s)}$("#alert-btn").click(function(s){$("#alert").addClass("d-none").removeClass("show")})</script><div class="accordion" id="accordion"><div class="card"><div class="card-header" id="headingFormat"><h2 class="mb-0"><button class="btn btn-link btn-block text-left" type="button" data-toggle="collapse" data-target="#collapseFormat" aria-expanded="true" aria-controls="collapseFormat">Push Format Templates</button></h2></div><div id="collapseFormat" class="collapse show" aria-labelledby="headingFormat" data-parent="#accordion"><div class="card-body"><input type="text" name="id" id="id" hidden> <input type="text" name="http-1" id="http-1" hidden> <input type="text" name="http-2" id="http-2" hidden><!--<input type="text" name="brewfather" id="brewfather" hidden>--> <input type="text" name="influxdb" id="influxdb" hidden> <input type="text" name="mqtt" id="mqtt" hidden><div class="form-group row"><label for="push-target" class="col-sm-2 col-form-label">Push target:</label> <select class="custom-select col-sm-4" required name="push-target" id="push-target"><option value="http-1">HTTP option 1</option><option value="http-2">HTTP option 2</option><!--<option value="brewfather">Brewfather</option>--><option value="influxdb">Influx DB</option><option value="mqtt">MQTT</option></select></div><div class="form-group row"><div class="col-sm-12"><textarea rows="5" class="form-control" name="format" id="format">
|
||||
</textarea></div></div><div class="form-group row"><div class="col-sm-8 offset-sm-2"><button class="btn btn-primary" id="format-btn">Save</button> <button class="btn btn-secondary" id="test-btn">Test</button></div></div><pre class="card-preview" id="preview" name="preview"></pre></div></div></div><hr class="my-4"></div><script type="text/javascript">function setButtonDisabled(e){$("#format-btn").prop("disabled",e),$("#test-btn").prop("disabled",e)}function selectFormat(){var e="#"+$("#push-target").val();console.log(e),e=decodeURIComponent($(e).val()),console.log(e),e=e.replaceAll("|","|\n"),console.log(e),$("#format").val(e),$("#preview").text("")}function getConfig(){setButtonDisabled(!0);var e="/api/config/format";$("#spinner").show(),$.getJSON(e,function(e){console.log(e),$("#id").val(e.id),$("#http-1").val(e["http-1"]),$("#http-2").val(e["http-2"]),$("#influxdb").val(e.influxdb),$("#mqtt").val(e.mqtt),selectFormat()}).fail(function(){showError("Unable to get data from the device.")}).always(function(){$("#spinner").hide(),setButtonDisabled(!1)})}window.onload=getConfig,setButtonDisabled(!0),$(document).ready(function(){null!=location.hash&&""!=location.hash&&($(".collapse").removeClass("in"),$(location.hash+".collapse").collapse("show"))}),$("#push-target").change(function(e){console.log(e),selectFormat()}),$("#format-btn").click(function(e){var l=$("#format").val();l=l.replaceAll("\n","");var t="id="+$("#id").val()+"&"+$("#push-target").val()+"="+encodeURIComponent(l);console.log(t),$.ajax({type:"POST",url:"/api/config/format",data:t,success:function(e){showSuccess("Format stored successfully."),getConfig()},error:function(e){showError("Unable to store format.")}})}),$("#test-btn").click(function(e){var l="/api/status";$("#spinner").show(),$.getJSON(l,function(e){console.log(e);var l=$("#format").val();if(l="C"==e["temp-format"]?l.replaceAll("${temp}",e["temp-c"]):l.replaceAll("${temp}",e["temp-f"]),"G"==e["gravity-format"]){var t=e.gravity;l=l.replaceAll("${gravity-sg}",t),l=l.replaceAll("${corr-gravity-sg}",t);var a=259-(259-t);l=l.replaceAll("${gravity-plato}",a),l=l.replaceAll("${corr-gravity-plato}",a)}else{a=e.gravity;l=l.replaceAll("${gravity-plato}",a),l=l.replaceAll("${corr-gravity-plato}",a);t=259/(259-a);l=l.replaceAll("${gravity-sg}",t),l=l.replaceAll("${corr-gravity-sg}",t)}l=l.replaceAll("${mdns}",e.mdns),l=l.replaceAll("${id}",e.id),l=l.replaceAll("${sleep-interval}",e["sleep-interval"]),l=l.replaceAll("${token}",e.token),l=l.replaceAll("${temp-c}",e["temp-c"]),l=l.replaceAll("${temp-f}",e["temp-f"]),l=l.replaceAll("${temp-unit}",e["temp-format"]),l=l.replaceAll("${battery}",e.battery),l=l.replaceAll("${rssi}",e.rssi),l=l.replaceAll("${run-time}",e["runtime-average"]),l=l.replaceAll("${gravity}",e.gravity),l=l.replaceAll("${gravity-unit}",e["gravity-format"]),l=l.replaceAll("${corr-gravity}",e.gravity),l=l.replaceAll("${angle}",e.angle),l=l.replaceAll("${tilt}",e.angle);try{var r=JSON.parse(l);l=JSON.stringify(r,null,2)}catch(e){console.log("Not a javascript object!")}$("#preview").text(l)}).fail(function(){showError("Unable to get data from the device.")}).always(function(){$("#spinner").hide()})})</script><!-- START FOOTER --><div class="container-fluid themed-container bg-primary text-light">(C) Copyright 2021-22 Magnus Persson</div></div></body></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 rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" 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://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" 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="javascript:history.back()">Back to configuration</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(s){$("#alert").removeClass("alert-success").addClass("alert-danger").removeClass("d-none").addClass("show"),$("#alert-msg").text(s)}function showSuccess(s){$("#alert").addClass("alert-success").removeClass("alert-danger").removeClass("d-none").addClass("show"),$("#alert-msg").text(s)}$("#alert-btn").click(function(s){$("#alert").addClass("d-none").removeClass("show")})</script><div class="accordion" id="accordion"><div class="card"><div class="card-header" id="headingFormat"><h2 class="mb-0"><button class="btn btn-link btn-block text-left" type="button" data-toggle="collapse" data-target="#collapseFormat" aria-expanded="true" aria-controls="collapseFormat">Push Format Templates</button></h2></div><div id="collapseFormat" class="collapse show" aria-labelledby="headingFormat" data-parent="#accordion"><div class="card-body"><input type="text" name="id" id="id" hidden> <input type="text" name="http-1" id="http-1" hidden> <input type="text" name="http-2" id="http-2" hidden> <input type="text" name="http-3" id="http-3" hidden><!--<input type="text" name="brewfather" id="brewfather" hidden>--> <input type="text" name="influxdb" id="influxdb" hidden> <input type="text" name="mqtt" id="mqtt" hidden><div class="form-group row"><label for="push-target" class="col-sm-2 col-form-label">Push target:</label> <select class="custom-select col-sm-4" required name="push-target" id="push-target"><option value="http-1">HTTP option 1 (post)</option><option value="http-2">HTTP option 2 (post)</option><option value="http-3">HTTP option 3 (get)</option><!--<option value="brewfather">Brewfather</option>--><option value="influxdb">Influx DB</option><option value="mqtt">MQTT</option></select></div><div class="form-group row"><div class="col-sm-12"><textarea rows="5" class="form-control" name="format" id="format">
|
||||
</textarea></div></div><div class="form-group row"><div class="col-sm-8 offset-sm-2"><button class="btn btn-primary" id="format-btn">Save</button> <button class="btn btn-secondary" id="test-btn">Test</button></div></div><pre class="card-preview" id="preview" name="preview"></pre></div></div></div><hr class="my-4"></div><script type="text/javascript">function setButtonDisabled(e){$("#format-btn").prop("disabled",e),$("#test-btn").prop("disabled",e)}function selectFormat(){var e="#"+$("#push-target").val();console.log(e),e=decodeURIComponent($(e).val()),console.log(e),e=e.replaceAll("|","|\n"),console.log(e),$("#format").val(e),$("#preview").text("")}function getConfig(){setButtonDisabled(!0);var e="/api/config/format";$("#spinner").show(),$.getJSON(e,function(e){console.log(e),$("#id").val(e.id),$("#http-1").val(e["http-1"]),$("#http-2").val(e["http-2"]),$("#http-3").val(e["http-3"]),$("#influxdb").val(e.influxdb),$("#mqtt").val(e.mqtt),selectFormat()}).fail(function(){showError("Unable to get data from the device.")}).always(function(){$("#spinner").hide(),setButtonDisabled(!1)})}window.onload=getConfig,setButtonDisabled(!0),$(document).ready(function(){null!=location.hash&&""!=location.hash&&($(".collapse").removeClass("in"),$(location.hash+".collapse").collapse("show"))}),$("#push-target").change(function(e){console.log(e),selectFormat()}),$("#format-btn").click(function(e){var l=$("#format").val();l=l.replaceAll("\n","");var t="id="+$("#id").val()+"&"+$("#push-target").val()+"="+encodeURIComponent(l);console.log(t),$.ajax({type:"POST",url:"/api/config/format",data:t,success:function(e){showSuccess("Format stored successfully."),getConfig()},error:function(e){showError("Unable to store format.")}})}),$("#test-btn").click(function(e){var l="/api/status";$("#spinner").show(),$.getJSON(l,function(e){console.log(e);var l=$("#format").val();if(l="C"==e["temp-format"]?l.replaceAll("${temp}",e["temp-c"]):l.replaceAll("${temp}",e["temp-f"]),"G"==e["gravity-format"]){var t=e.gravity;l=l.replaceAll("${gravity-sg}",t),l=l.replaceAll("${corr-gravity-sg}",t);var a=259-(259-t);l=l.replaceAll("${gravity-plato}",a),l=l.replaceAll("${corr-gravity-plato}",a)}else{a=e.gravity;l=l.replaceAll("${gravity-plato}",a),l=l.replaceAll("${corr-gravity-plato}",a);t=259/(259-a);l=l.replaceAll("${gravity-sg}",t),l=l.replaceAll("${corr-gravity-sg}",t)}l=l.replaceAll("${mdns}",e.mdns),l=l.replaceAll("${id}",e.id),l=l.replaceAll("${sleep-interval}",e["sleep-interval"]),l=l.replaceAll("${token}",e.token),l=l.replaceAll("${token2}",e.token2),l=l.replaceAll("${temp-c}",e["temp-c"]),l=l.replaceAll("${temp-f}",e["temp-f"]),l=l.replaceAll("${temp-unit}",e["temp-format"]),l=l.replaceAll("${battery}",e.battery),l=l.replaceAll("${rssi}",e.rssi),l=l.replaceAll("${run-time}",e["runtime-average"]),l=l.replaceAll("${gravity}",e.gravity),l=l.replaceAll("${gravity-unit}",e["gravity-format"]),l=l.replaceAll("${corr-gravity}",e.gravity),l=l.replaceAll("${angle}",e.angle),l=l.replaceAll("${tilt}",e.angle);try{var r=JSON.parse(l);l=JSON.stringify(r,null,2)}catch(e){console.log("Not a javascript object!")}$("#preview").text(l)}).fail(function(){showError("Unable to get data from the device.")}).always(function(){$("#spinner").hide()})})</script><!-- START FOOTER --><div class="container-fluid themed-container bg-primary text-light">(C) Copyright 2021-22 Magnus Persson</div></div></body></html>
|
@ -91,6 +91,7 @@
|
||||
|
||||
testHttp( id, "http-1" );
|
||||
testHttp( id, "http-2" );
|
||||
testHttp( id, "http-3" );
|
||||
testHttp( id, "brewfather" );
|
||||
testInfluxdb( id );
|
||||
testMqtt( id );
|
||||
|
@ -1 +1 @@
|
||||
<!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 rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" 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://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" 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="javascript:history.back()">Back to configuration</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(s){$("#alert").removeClass("alert-success").addClass("alert-danger").removeClass("d-none").addClass("show"),$("#alert-msg").text(s)}function showSuccess(s){$("#alert").addClass("alert-success").removeClass("alert-danger").removeClass("d-none").addClass("show"),$("#alert-msg").text(s)}$("#alert-btn").click(function(s){$("#alert").addClass("d-none").removeClass("show")})</script><div><div class="card"><div class="card-body"><pre class="card-preview" id="preview" name="preview"></pre></div></div><hr class="my-4"></div><script type="text/javascript">function appendLog(t){doc=$("#preview").text(),doc+=t+"\n",$("#preview").text(doc)}function getConfig(){appendLog("Starting test of push targets");var t="/api/status";$("#spinner").show(),$.getJSON(t,function(t){var e=t.id;console.log(e),testHttp(e,"http-1"),testHttp(e,"http-2"),testHttp(e,"brewfather"),testInfluxdb(e),testMqtt(e)}).fail(function(){showError("Unable to get data from the device.")}).always(function(){$("#spinner").hide()})}function testMqtt(t){var e="/api/test/push";e+="?id="+t+"&format=mqtt",$.getJSON(e,function(t){var e=t.code,r=t.success,o=t.enabled;appendLog(o?r?"Push target 'mqtt' successful":-3==e?"Push target 'mqtt' failed to connect":-4==e?"Push target 'mqtt' failed with error timeout":-10==e?"Push target 'mqtt' failed with error denied":"Push target 'mqtt' failed with error code "+e:"Push target 'mqtt' is not configured/used")}).fail(function(){appendLog("Failed to test push target 'influxdb'")})}function testInfluxdb(t){var e="/api/test/push";e+="?id="+t+"&format=influxdb",$.getJSON(e,function(t){var e=t.code,r=t.success,o=t.enabled;appendLog(o?r?"Push target 'influxdb' successful":400==e?"Push target 'influxdb' failed with error code 400, bad request":401==e?"Push target 'influxdb' failed with error code 401, unauthorized":404==e?"Push target 'influxdb' failed with error code 404, url not found":"Push target 'influxdb' failed with error code "+e:"Push target 'influxdb' is not configured/used")}).fail(function(){appendLog("Failed to test push target 'influxdb'")})}function testHttp(t,i){var e="/api/test/push";e+="?id="+t+"&format="+i,$.getJSON(e,function(t){var e=t.code,r=t.success,o=t.enabled;appendLog(o?r?"Push target '"+i+"' successful":400==e?"Push target '"+i+"' failed with error code 400, bad request":401==e?"Push target '"+i+"' failed with error code 401, unauthorized":404==e?"Push target '"+i+"' failed with error code 404, url not found":"Push target '"+i+"' failed with error code "+e:"Push target '"+i+"' is not configured/used")}).fail(function(){appendLog("Failed to test push target '"+i+"'")})}window.onload=getConfig</script><!-- START FOOTER --><div class="container-fluid themed-container bg-primary text-light">(C) Copyright 2021-22 Magnus Persson</div></div></body></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 rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" 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://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" 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="javascript:history.back()">Back to configuration</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(s){$("#alert").removeClass("alert-success").addClass("alert-danger").removeClass("d-none").addClass("show"),$("#alert-msg").text(s)}function showSuccess(s){$("#alert").addClass("alert-success").removeClass("alert-danger").removeClass("d-none").addClass("show"),$("#alert-msg").text(s)}$("#alert-btn").click(function(s){$("#alert").addClass("d-none").removeClass("show")})</script><div><div class="card"><div class="card-body"><pre class="card-preview" id="preview" name="preview"></pre></div></div><hr class="my-4"></div><script type="text/javascript">function appendLog(t){doc=$("#preview").text(),doc+=t+"\n",$("#preview").text(doc)}function getConfig(){appendLog("Starting test of push targets");var t="/api/status";$("#spinner").show(),$.getJSON(t,function(t){var e=t.id;console.log(e),testHttp(e,"http-1"),testHttp(e,"http-2"),testHttp(e,"http-3"),testHttp(e,"brewfather"),testInfluxdb(e),testMqtt(e)}).fail(function(){showError("Unable to get data from the device.")}).always(function(){$("#spinner").hide()})}function testMqtt(t){var e="/api/test/push";e+="?id="+t+"&format=mqtt",$.getJSON(e,function(t){var e=t.code,r=t.success,o=t.enabled;appendLog(o?r?"Push target 'mqtt' successful":-3==e?"Push target 'mqtt' failed to connect":-4==e?"Push target 'mqtt' failed with error timeout":-10==e?"Push target 'mqtt' failed with error denied":"Push target 'mqtt' failed with error code "+e:"Push target 'mqtt' is not configured/used")}).fail(function(){appendLog("Failed to test push target 'influxdb'")})}function testInfluxdb(t){var e="/api/test/push";e+="?id="+t+"&format=influxdb",$.getJSON(e,function(t){var e=t.code,r=t.success,o=t.enabled;appendLog(o?r?"Push target 'influxdb' successful":400==e?"Push target 'influxdb' failed with error code 400, bad request":401==e?"Push target 'influxdb' failed with error code 401, unauthorized":404==e?"Push target 'influxdb' failed with error code 404, url not found":"Push target 'influxdb' failed with error code "+e:"Push target 'influxdb' is not configured/used")}).fail(function(){appendLog("Failed to test push target 'influxdb'")})}function testHttp(t,i){var e="/api/test/push";e+="?id="+t+"&format="+i,$.getJSON(e,function(t){var e=t.code,r=t.success,o=t.enabled;appendLog(o?r?"Push target '"+i+"' successful":400==e?"Push target '"+i+"' failed with error code 400, bad request":401==e?"Push target '"+i+"' failed with error code 401, unauthorized":404==e?"Push target '"+i+"' failed with error code 404, url not found":"Push target '"+i+"' failed with error code "+e:"Push target '"+i+"' is not configured/used")}).fail(function(){appendLog("Failed to test push target '"+i+"'")})}window.onload=getConfig</script><!-- START FOOTER --><div class="container-fluid themed-container bg-primary text-light">(C) Copyright 2021-22 Magnus Persson</div></div></body></html>
|
@ -74,12 +74,14 @@ void Config::createJson(DynamicJsonDocument& doc) {
|
||||
doc[PARAM_TEMPFORMAT] = String(getTempFormat());
|
||||
doc[PARAM_PUSH_BREWFATHER] = getBrewfatherPushUrl();
|
||||
doc[PARAM_TOKEN] = getToken();
|
||||
doc[PARAM_TOKEN2] = getToken2();
|
||||
doc[PARAM_PUSH_HTTP] = getHttpUrl();
|
||||
doc[PARAM_PUSH_HTTP_H1] = getHttpHeader(0);
|
||||
doc[PARAM_PUSH_HTTP_H2] = getHttpHeader(1);
|
||||
doc[PARAM_PUSH_HTTP2] = getHttp2Url();
|
||||
doc[PARAM_PUSH_HTTP2_H1] = getHttp2Header(0);
|
||||
doc[PARAM_PUSH_HTTP2_H2] = getHttp2Header(1);
|
||||
doc[PARAM_PUSH_HTTP3] = getHttp3Url();
|
||||
doc[PARAM_PUSH_INFLUXDB2] = getInfluxDb2PushUrl();
|
||||
doc[PARAM_PUSH_INFLUXDB2_ORG] = getInfluxDb2PushOrg();
|
||||
doc[PARAM_PUSH_INFLUXDB2_BUCKET] = getInfluxDb2PushBucket();
|
||||
@ -215,6 +217,7 @@ bool Config::loadFile() {
|
||||
setBrewfatherPushUrl(doc[PARAM_PUSH_BREWFATHER]);
|
||||
|
||||
if (!doc[PARAM_TOKEN].isNull()) setToken(doc[PARAM_TOKEN]);
|
||||
if (!doc[PARAM_TOKEN2].isNull()) setToken2(doc[PARAM_TOKEN2]);
|
||||
if (!doc[PARAM_PUSH_HTTP].isNull()) setHttpUrl(doc[PARAM_PUSH_HTTP]);
|
||||
if (!doc[PARAM_PUSH_HTTP_H1].isNull())
|
||||
setHttpHeader(doc[PARAM_PUSH_HTTP_H1], 0);
|
||||
@ -225,6 +228,7 @@ bool Config::loadFile() {
|
||||
setHttp2Header(doc[PARAM_PUSH_HTTP2_H1], 0);
|
||||
if (!doc[PARAM_PUSH_HTTP2_H2].isNull())
|
||||
setHttp2Header(doc[PARAM_PUSH_HTTP2_H2], 1);
|
||||
if (!doc[PARAM_PUSH_HTTP3].isNull()) setHttp3Url(doc[PARAM_PUSH_HTTP3]);
|
||||
|
||||
if (!doc[PARAM_PUSH_INFLUXDB2].isNull())
|
||||
setInfluxDb2PushUrl(doc[PARAM_PUSH_INFLUXDB2]);
|
||||
|
@ -109,11 +109,13 @@ class Config {
|
||||
String _brewfatherPushUrl = "";
|
||||
|
||||
String _token = "";
|
||||
String _token2 = "";
|
||||
|
||||
String _httpUrl = "";
|
||||
String _httpHeader[2] = {"Content-Type: application/json", ""};
|
||||
String _http2Url = "";
|
||||
String _http2Header[2] = {"Content-Type: application/json", ""};
|
||||
String _http3Url = "";
|
||||
|
||||
String _influxDb2Url = "";
|
||||
String _influxDb2Org = "";
|
||||
@ -192,6 +194,11 @@ class Config {
|
||||
_token = s;
|
||||
_saveNeeded = true;
|
||||
}
|
||||
const char* getToken2() { return _token2.c_str(); }
|
||||
void setToken2(String s) {
|
||||
_token2 = s;
|
||||
_saveNeeded = true;
|
||||
}
|
||||
|
||||
// Standard HTTP
|
||||
const char* getHttpUrl() { return _httpUrl.c_str(); }
|
||||
@ -220,6 +227,14 @@ class Config {
|
||||
bool isHttp2Active() { return _http2Url.length() ? true : false; }
|
||||
bool isHttp2SSL() { return _http2Url.startsWith("https://"); }
|
||||
|
||||
const char* getHttp3Url() { return _http3Url.c_str(); }
|
||||
void setHttp3Url(String s) {
|
||||
_http3Url = s;
|
||||
_saveNeeded = true;
|
||||
}
|
||||
bool isHttp3Active() { return _http3Url.length() ? true : false; }
|
||||
bool isHttp3SSL() { return _http3Url.startsWith("https://"); }
|
||||
|
||||
// InfluxDB2
|
||||
const char* getInfluxDb2PushUrl() { return _influxDb2Url.c_str(); }
|
||||
void setInfluxDb2PushUrl(String s) {
|
||||
@ -345,7 +360,7 @@ class Config {
|
||||
}
|
||||
bool isBLEActive() { return _colorBLE.length() ? true : false; }
|
||||
bool isWifiPushActive() {
|
||||
return (isHttpActive() || isHttp2Active() || isBrewfatherActive() || isInfluxDb2Active() || isMqttActive()) ? true : false;
|
||||
return (isHttpActive() || isHttp2Active() || isHttp3Active() || isBrewfatherActive() || isInfluxDb2Active() || isMqttActive()) ? true : false;
|
||||
}
|
||||
|
||||
const RawGyroData& getGyroCalibration() { return _gyroCalibration; }
|
||||
|
@ -52,16 +52,22 @@ void PushTarget::sendAll(float angle, float gravitySG, float corrGravitySG,
|
||||
|
||||
if (myConfig.isHttpActive()) {
|
||||
LOG_PERF_START("push-http");
|
||||
sendHttp(engine, myConfig.isHttpSSL(), 0);
|
||||
sendHttpPost(engine, myConfig.isHttpSSL(), 0);
|
||||
LOG_PERF_STOP("push-http");
|
||||
}
|
||||
|
||||
if (myConfig.isHttp2Active()) {
|
||||
LOG_PERF_START("push-http2");
|
||||
sendHttp(engine, myConfig.isHttp2SSL(), 1);
|
||||
sendHttpPost(engine, myConfig.isHttp2SSL(), 1);
|
||||
LOG_PERF_STOP("push-http2");
|
||||
}
|
||||
|
||||
if (myConfig.isHttp3Active()) {
|
||||
LOG_PERF_START("push-http3");
|
||||
sendHttpGet(engine, myConfig.isHttp3SSL());
|
||||
LOG_PERF_STOP("push-http3");
|
||||
}
|
||||
|
||||
if (myConfig.isInfluxDb2Active()) {
|
||||
LOG_PERF_START("push-influxdb2");
|
||||
sendInfluxDb2(engine);
|
||||
@ -178,9 +184,9 @@ void PushTarget::addHttpHeader(HTTPClient& http, String header) {
|
||||
}
|
||||
|
||||
//
|
||||
// Send data to http target
|
||||
// Send data to http target using POST
|
||||
//
|
||||
void PushTarget::sendHttp(TemplatingEngine& engine, bool isSecure, int index) {
|
||||
void PushTarget::sendHttpPost(TemplatingEngine& engine, bool isSecure, int index) {
|
||||
#if !defined(PUSH_DISABLE_LOGGING)
|
||||
Log.notice(F("PUSH: Sending values to http (%s)" CR),
|
||||
index ? "http2" : "http");
|
||||
@ -248,12 +254,12 @@ void PushTarget::sendHttp(TemplatingEngine& engine, bool isSecure, int index) {
|
||||
|
||||
if (_lastCode == 200) {
|
||||
_lastSuccess = true;
|
||||
Log.notice(F("PUSH: HTTP push successful, response=%d" CR),
|
||||
Log.notice(F("PUSH: HTTP post successful, response=%d" CR),
|
||||
_lastCode);
|
||||
} else {
|
||||
ErrorFileLog errLog;
|
||||
errLog.addEntry(
|
||||
"PUSH: HTTP push failed response=" + String(_lastCode) +
|
||||
"PUSH: HTTP post failed response=" + String(_lastCode) +
|
||||
String(index == 0 ? " (http)" : " (http2)"));
|
||||
}
|
||||
|
||||
@ -268,7 +274,71 @@ void PushTarget::sendHttp(TemplatingEngine& engine, bool isSecure, int index) {
|
||||
}
|
||||
|
||||
//
|
||||
// Send data to http target
|
||||
// Send data to http target using GET
|
||||
//
|
||||
void PushTarget::sendHttpGet(TemplatingEngine& engine, bool isSecure) {
|
||||
#if !defined(PUSH_DISABLE_LOGGING)
|
||||
Log.notice(F("PUSH: Sending values to http3" CR));
|
||||
#endif
|
||||
_lastCode = 0;
|
||||
_lastSuccess = false;
|
||||
|
||||
String serverPath;
|
||||
|
||||
serverPath = myConfig.getHttp3Url();
|
||||
serverPath += engine.create(TemplatingEngine::TEMPLATE_HTTP3);
|
||||
|
||||
#if LOG_LEVEL == 6 && !defined(PUSH_DISABLE_LOGGING)
|
||||
Log.verbose(F("PUSH: url %s." CR), serverPath.c_str());
|
||||
#endif
|
||||
|
||||
if (isSecure) {
|
||||
Log.notice(F("PUSH: HTTP, SSL enabled without validation." CR));
|
||||
_wifiSecure.setInsecure();
|
||||
|
||||
#if defined (ESP8266)
|
||||
String host = serverPath.substring(8); // remove the prefix or the probe will fail, it needs a pure host name.
|
||||
int idx = host.indexOf("/");
|
||||
if (idx!=-1)
|
||||
host = host.substring(0, idx);
|
||||
|
||||
if (_wifiSecure.probeMaxFragmentLength(host, 443, 512)) {
|
||||
Log.notice(F("PUSH: HTTP server supports smaller SSL buffer." CR));
|
||||
_wifiSecure.setBufferSizes(512, 512);
|
||||
}
|
||||
#endif
|
||||
|
||||
_httpSecure.begin(_wifiSecure, serverPath);
|
||||
_httpSecure.setTimeout(myHardwareConfig.getPushTimeout() * 1000);
|
||||
_lastCode = _httpSecure.GET();
|
||||
} else {
|
||||
_http.begin(_wifi, serverPath);
|
||||
_http.setTimeout(myHardwareConfig.getPushTimeout() * 1000);
|
||||
_lastCode = _http.GET();
|
||||
}
|
||||
|
||||
if (_lastCode == 200) {
|
||||
_lastSuccess = true;
|
||||
Log.notice(F("PUSH: HTTP get successful, response=%d" CR),
|
||||
_lastCode);
|
||||
} else {
|
||||
ErrorFileLog errLog;
|
||||
errLog.addEntry(
|
||||
"PUSH: HTTP get failed response=" + String(_lastCode));
|
||||
}
|
||||
|
||||
if (isSecure) {
|
||||
_httpSecure.end();
|
||||
_wifiSecure.stop();
|
||||
} else {
|
||||
_http.end();
|
||||
_wifi.stop();
|
||||
}
|
||||
tcp_cleanup();
|
||||
}
|
||||
|
||||
//
|
||||
// Send data to mqtt target
|
||||
//
|
||||
void PushTarget::sendMqtt(TemplatingEngine& engine, bool isSecure) {
|
||||
#if !defined(PUSH_DISABLE_LOGGING)
|
||||
|
@ -42,7 +42,8 @@ class PushTarget {
|
||||
int _lastCode;
|
||||
bool _lastSuccess;
|
||||
|
||||
void sendHttp(TemplatingEngine& engine, bool isSecure, int index);
|
||||
void sendHttpPost(TemplatingEngine& engine, bool isSecure, int index);
|
||||
void sendHttpGet(TemplatingEngine& engine, bool isSecure);
|
||||
void addHttpHeader(HTTPClient& http, String header);
|
||||
|
||||
public:
|
||||
@ -50,8 +51,9 @@ class PushTarget {
|
||||
float runTime);
|
||||
|
||||
void sendBrewfather(TemplatingEngine& engine);
|
||||
void sendHttp1(TemplatingEngine& engine, bool isSecure) { sendHttp(engine, isSecure, 0); }
|
||||
void sendHttp2(TemplatingEngine& engine, bool isSecure) { sendHttp(engine, isSecure, 1); }
|
||||
void sendHttp1(TemplatingEngine& engine, bool isSecure) { sendHttpPost(engine, isSecure, 0); }
|
||||
void sendHttp2(TemplatingEngine& engine, bool isSecure) { sendHttpPost(engine, isSecure, 1); }
|
||||
void sendHttp3(TemplatingEngine& engine, bool isSecure) { sendHttpGet(engine, isSecure); }
|
||||
void sendInfluxDb2(TemplatingEngine& engine);
|
||||
void sendMqtt(TemplatingEngine& engine, bool isSecure);
|
||||
int getLastCode() { return _lastCode; }
|
||||
|
@ -34,12 +34,14 @@ SOFTWARE.
|
||||
#define PARAM_RUNTIME_AVERAGE "runtime-average"
|
||||
#define PARAM_PUSH_BREWFATHER "brewfather-push"
|
||||
#define PARAM_TOKEN "token"
|
||||
#define PARAM_TOKEN2 "token2"
|
||||
#define PARAM_PUSH_HTTP "http-push"
|
||||
#define PARAM_PUSH_HTTP_H1 "http-push-h1"
|
||||
#define PARAM_PUSH_HTTP_H2 "http-push-h2"
|
||||
#define PARAM_PUSH_HTTP2 "http-push2"
|
||||
#define PARAM_PUSH_HTTP2_H1 "http-push2-h1"
|
||||
#define PARAM_PUSH_HTTP2_H2 "http-push2-h2"
|
||||
#define PARAM_PUSH_HTTP3 "http-push3"
|
||||
#define PARAM_PUSH_INFLUXDB2 "influxdb2-push"
|
||||
#define PARAM_PUSH_INFLUXDB2_ORG "influxdb2-org"
|
||||
#define PARAM_PUSH_INFLUXDB2_BUCKET "influxdb2-bucket"
|
||||
@ -81,6 +83,7 @@ SOFTWARE.
|
||||
#define PARAM_HW_PUSH_TIMEOUT "push-timeout"
|
||||
#define PARAM_FORMAT_HTTP1 "http-1"
|
||||
#define PARAM_FORMAT_HTTP2 "http-2"
|
||||
#define PARAM_FORMAT_HTTP3 "http-3"
|
||||
#define PARAM_FORMAT_BREWFATHER "brewfather"
|
||||
#define PARAM_FORMAT_INFLUXDB "influxdb"
|
||||
#define PARAM_FORMAT_MQTT "mqtt"
|
||||
|
@ -30,7 +30,7 @@ SOFTWARE.
|
||||
#include <WiFi.h>
|
||||
#endif
|
||||
|
||||
// Use iSpindle format for compatibility
|
||||
// Use iSpindle format for compatibility, HTTP POST
|
||||
const char iSpindleFormat[] PROGMEM =
|
||||
"{"
|
||||
"\"name\" : \"${mdns}\", "
|
||||
@ -48,6 +48,22 @@ const char iSpindleFormat[] PROGMEM =
|
||||
"\"run-time\": ${run-time} "
|
||||
"}";
|
||||
|
||||
// Format for an HTTP GET
|
||||
const char iHttpGetFormat[] PROGMEM =
|
||||
"?name=${mdns}"
|
||||
"&id=${id}"
|
||||
"&token=${token2}"
|
||||
"&interval=${sleep-interval}"
|
||||
"&temperature=${temp}"
|
||||
"&temp-units=${temp-unit}"
|
||||
"&gravity=${gravity}"
|
||||
"&angle=${angle}"
|
||||
"&battery=${battery}"
|
||||
"&rssi=${rssi}"
|
||||
"&corr-gravity=${corr-gravity}"
|
||||
"&gravity-unit=${gravity-unit}"
|
||||
"&run-time=${run-time}";
|
||||
|
||||
const char brewfatherFormat[] PROGMEM =
|
||||
"{"
|
||||
"\"name\": \"${mdns}\","
|
||||
@ -89,6 +105,7 @@ void TemplatingEngine::initialize(float angle, float gravitySG, float corrGravit
|
||||
setVal(TPL_MDNS, myConfig.getMDNS());
|
||||
setVal(TPL_ID, myConfig.getID());
|
||||
setVal(TPL_TOKEN, myConfig.getToken());
|
||||
setVal(TPL_TOKEN2, myConfig.getToken2());
|
||||
|
||||
// Temperature
|
||||
if (myConfig.isTempC()) {
|
||||
@ -151,6 +168,10 @@ const String& TemplatingEngine::create(TemplatingEngine::Templates idx) {
|
||||
baseTemplate = String(iSpindleFormat);
|
||||
fname = TPL_FNAME_HTTP2;
|
||||
break;
|
||||
case TEMPLATE_HTTP3:
|
||||
baseTemplate = String(iHttpGetFormat);
|
||||
fname = TPL_FNAME_HTTP3;
|
||||
break;
|
||||
case TEMPLATE_BREWFATHER:
|
||||
baseTemplate = String(brewfatherFormat);
|
||||
//fname = TPL_FNAME_BREWFATHER;
|
||||
|
@ -35,6 +35,7 @@ SOFTWARE.
|
||||
#define TPL_MDNS "${mdns}"
|
||||
#define TPL_ID "${id}"
|
||||
#define TPL_TOKEN "${token}"
|
||||
#define TPL_TOKEN2 "${token2}"
|
||||
#define TPL_SLEEP_INTERVAL "${sleep-interval}"
|
||||
#define TPL_TEMP "${temp}"
|
||||
#define TPL_TEMP_C "${temp-c}"
|
||||
@ -55,11 +56,13 @@ SOFTWARE.
|
||||
|
||||
#define TPL_FNAME_HTTP1 "/http-1.tpl"
|
||||
#define TPL_FNAME_HTTP2 "/http-2.tpl"
|
||||
#define TPL_FNAME_HTTP3 "/http-3.tpl"
|
||||
// #define TPL_FNAME_BREWFATHER "/brewfather.tpl"
|
||||
#define TPL_FNAME_INFLUXDB "/influxdb.tpl"
|
||||
#define TPL_FNAME_MQTT "/mqtt.tpl"
|
||||
|
||||
extern const char iSpindleFormat[] PROGMEM;
|
||||
extern const char iHttpGetFormat[] PROGMEM;
|
||||
extern const char brewfatherFormat[] PROGMEM;
|
||||
extern const char influxDbFormat[] PROGMEM;
|
||||
extern const char mqttFormat[] PROGMEM;
|
||||
@ -72,7 +75,7 @@ class TemplatingEngine {
|
||||
String val;
|
||||
};
|
||||
|
||||
KeyVal items[20] = {{TPL_MDNS, ""}, {TPL_ID, ""},
|
||||
KeyVal items[21] = {{TPL_MDNS, ""}, {TPL_ID, ""},
|
||||
{TPL_SLEEP_INTERVAL, ""}, {TPL_TEMP, ""},
|
||||
{TPL_TEMP_C, ""}, {TPL_TEMP_F, ""},
|
||||
{TPL_TEMP_UNITS, ""}, {TPL_BATTERY, ""},
|
||||
@ -81,7 +84,8 @@ class TemplatingEngine {
|
||||
{TPL_GRAVITY, ""}, {TPL_GRAVITY_G, ""},
|
||||
{TPL_GRAVITY_P, ""}, {TPL_GRAVITY_CORR, ""},
|
||||
{TPL_GRAVITY_CORR_G, ""}, {TPL_GRAVITY_CORR_P, ""},
|
||||
{TPL_GRAVITY_UNIT, ""}, {TPL_TOKEN, ""}};
|
||||
{TPL_GRAVITY_UNIT, ""}, {TPL_TOKEN, ""},
|
||||
{TPL_TOKEN2, ""} };
|
||||
|
||||
char buffer[20];
|
||||
String baseTemplate;
|
||||
@ -128,9 +132,10 @@ class TemplatingEngine {
|
||||
enum Templates {
|
||||
TEMPLATE_HTTP1 = 0,
|
||||
TEMPLATE_HTTP2 = 1,
|
||||
TEMPLATE_BREWFATHER = 2,
|
||||
TEMPLATE_INFLUX = 3,
|
||||
TEMPLATE_MQTT = 4
|
||||
TEMPLATE_HTTP3 = 2,
|
||||
TEMPLATE_BREWFATHER = 3,
|
||||
TEMPLATE_INFLUX = 4,
|
||||
TEMPLATE_MQTT = 5
|
||||
};
|
||||
|
||||
void initialize(float angle, float gravitySG, float corrGravitySG,
|
||||
|
@ -285,6 +285,7 @@ void WebServerHandler::webHandleStatus() {
|
||||
doc[PARAM_RSSI] = WiFi.RSSI();
|
||||
doc[PARAM_SLEEP_INTERVAL] = myConfig.getSleepInterval();
|
||||
doc[PARAM_TOKEN] = myConfig.getToken();
|
||||
doc[PARAM_TOKEN2] = myConfig.getToken2();
|
||||
|
||||
doc[PARAM_APP_VER] = CFG_APPVER;
|
||||
doc[PARAM_MDNS] = myConfig.getMDNS();
|
||||
@ -413,6 +414,8 @@ void WebServerHandler::webHandleConfigPush() {
|
||||
|
||||
if (_server->hasArg(PARAM_TOKEN))
|
||||
myConfig.setToken(_server->arg(PARAM_TOKEN).c_str());
|
||||
if (_server->hasArg(PARAM_TOKEN2))
|
||||
myConfig.setToken2(_server->arg(PARAM_TOKEN2).c_str());
|
||||
if (_server->hasArg(PARAM_PUSH_HTTP))
|
||||
myConfig.setHttpUrl(_server->arg(PARAM_PUSH_HTTP).c_str());
|
||||
if (_server->hasArg(PARAM_PUSH_HTTP_H1))
|
||||
@ -425,6 +428,8 @@ void WebServerHandler::webHandleConfigPush() {
|
||||
myConfig.setHttp2Header(_server->arg(PARAM_PUSH_HTTP2_H1).c_str(), 0);
|
||||
if (_server->hasArg(PARAM_PUSH_HTTP2_H2))
|
||||
myConfig.setHttp2Header(_server->arg(PARAM_PUSH_HTTP2_H2).c_str(), 1);
|
||||
if (_server->hasArg(PARAM_PUSH_HTTP3))
|
||||
myConfig.setHttp3Url(_server->arg(PARAM_PUSH_HTTP3).c_str());
|
||||
if (_server->hasArg(PARAM_PUSH_BREWFATHER))
|
||||
myConfig.setBrewfatherPushUrl(_server->arg(PARAM_PUSH_BREWFATHER).c_str());
|
||||
if (_server->hasArg(PARAM_PUSH_INFLUXDB2))
|
||||
@ -710,6 +715,8 @@ void WebServerHandler::webHandleConfigFormatWrite() {
|
||||
success = writeFile(TPL_FNAME_HTTP1, _server->arg(PARAM_FORMAT_HTTP1));
|
||||
} else if (_server->hasArg(PARAM_FORMAT_HTTP2)) {
|
||||
success = writeFile(TPL_FNAME_HTTP2, _server->arg(PARAM_FORMAT_HTTP2));
|
||||
} else if (_server->hasArg(PARAM_FORMAT_HTTP3)) {
|
||||
success = writeFile(TPL_FNAME_HTTP3, _server->arg(PARAM_FORMAT_HTTP3));
|
||||
} else if (_server->hasArg(PARAM_FORMAT_INFLUXDB)) {
|
||||
success =
|
||||
writeFile(TPL_FNAME_INFLUXDB, _server->arg(PARAM_FORMAT_INFLUXDB));
|
||||
@ -774,6 +781,9 @@ void WebServerHandler::webHandleTestPush() {
|
||||
} else if (!type.compareTo(PARAM_FORMAT_HTTP2) && myConfig.isHttp2Active()) {
|
||||
push.sendHttp2(engine, myConfig.isHttp2SSL());
|
||||
enabled = true;
|
||||
} else if (!type.compareTo(PARAM_FORMAT_HTTP3) && myConfig.isHttp3Active()) {
|
||||
push.sendHttp3(engine, myConfig.isHttp3SSL());
|
||||
enabled = true;
|
||||
} else if (!type.compareTo(PARAM_FORMAT_INFLUXDB) && myConfig.isInfluxDb2Active()) {
|
||||
push.sendInfluxDb2(engine);
|
||||
enabled = true;
|
||||
@ -868,6 +878,12 @@ void WebServerHandler::webHandleConfigFormatRead() {
|
||||
else
|
||||
doc[PARAM_FORMAT_HTTP2] = urlencode(String(&iSpindleFormat[0]));
|
||||
|
||||
s = readFile(TPL_FNAME_HTTP3);
|
||||
if (s.length())
|
||||
doc[PARAM_FORMAT_HTTP3] = urlencode(s);
|
||||
else
|
||||
doc[PARAM_FORMAT_HTTP3] = urlencode(String(&iHttpGetFormat[0]));
|
||||
|
||||
/*s = readFile(TPL_FNAME_BREWFATHER);
|
||||
if (s.length())
|
||||
doc[PARAM_FORMAT_BREWFATHER] = urlencode(s);
|
||||
|
@ -35,6 +35,12 @@ These are the format keys available for use in the format.
|
||||
* - ${mdns}
|
||||
- Name of the device
|
||||
- gravmon2
|
||||
* - ${token}
|
||||
- Token
|
||||
- any value
|
||||
* - ${token2}
|
||||
- Token 2
|
||||
- any value
|
||||
* - ${id}
|
||||
- Unique id of the device
|
||||
- e422a3
|
||||
|
@ -26,12 +26,14 @@ Other parameters are the same as in the configuration guide.
|
||||
"ble": "color",
|
||||
"brewfather-push": "http://log.brewfather.net/stream?id=Qwerty",
|
||||
"token": "token",
|
||||
"token2": "token2",
|
||||
"http-push": "http://192.168.1.50:9090/api/v1/Qwerty/telemetry",
|
||||
"http-push-h1": "header: value",
|
||||
"http-push-h2": "header: value",
|
||||
"http-push2": "http://192.168.1.50/ispindel",
|
||||
"http-push2-h1": "header: value",
|
||||
"http-push2-h2": "header: value",
|
||||
"http-push3": "http://192.168.1.50/ispindel",
|
||||
"influxdb2-push": "http://192.168.1.50:8086",
|
||||
"influxdb2-org": "org",
|
||||
"influxdb2-bucket": "bucket_id",
|
||||
@ -103,6 +105,7 @@ Other parameters are the same as in the configuration guide.
|
||||
"temp-format": "C",
|
||||
"sleep-mode": false,
|
||||
"token": "token",
|
||||
"token2": "token2",
|
||||
"rssi": -56,
|
||||
"app-ver": "0.0.0",
|
||||
"mdns": "gravmon",
|
||||
@ -211,8 +214,11 @@ Payload should be in standard format used for posting a form. Such as as: `id=va
|
||||
.. code-block::
|
||||
|
||||
id=ee1bfc
|
||||
token=
|
||||
token2=
|
||||
http-push=http://192.168.1.50/ispindel
|
||||
http-push2=
|
||||
http-push3=
|
||||
http-push-h1=
|
||||
http-push-h2=
|
||||
http-push2-h1=
|
||||
@ -332,8 +338,10 @@ The requests package converts the json to standard form post format.
|
||||
url = "http://" + host + "/api/config/push"
|
||||
json = { "id": id,
|
||||
"token": "",
|
||||
"token2": "",
|
||||
"http-push": "http://192.168.1.1/ispindel",
|
||||
"http-push2": "",
|
||||
"http-push3": "",
|
||||
"http-push-h1": "",
|
||||
"http-push-h2": "",
|
||||
"http-push2-h1": ""
|
||||
|
@ -92,13 +92,13 @@ Push Settings
|
||||
When enabling SSL this will not validate the root CA of the remote service, this is a design decision based on two aspects. Enabling CA validation will take 3-4s extra on each connection which means way less
|
||||
battery life, so the decision is to prioritize battery life over security. The data transmitted is not really that sensitive anyway so I belive this is a good balance.
|
||||
|
||||
* **HTTP URL 1:**
|
||||
* **HTTP 1 (POST):**
|
||||
|
||||
Endpoint to send data via http. Default format used Format used :ref:`data-formats-ispindle`. You can customize the format using :ref:`format-editor`.
|
||||
|
||||
If you add the prefix `https://` then the device will use SSL when sending data.
|
||||
|
||||
* **HTTP URL 2:**
|
||||
* **HTTP 2 (POST):**
|
||||
|
||||
Endpoint to send data via http. Default format used :ref:`data-formats-ispindle`. You can customize the format using :ref:`format-editor`.
|
||||
|
||||
@ -109,6 +109,16 @@ Push Settings
|
||||
The token is included in the iSpindle JSON format and will be used for both HTTP targets. If you
|
||||
need to have 2 different tokens please use the :ref:`format-editor` to customize the data format.
|
||||
|
||||
* **HTTP 3 (GET):**
|
||||
|
||||
Endpoint to send data via http. This is using an HTTP GET request instead of a post. This means that the values are appended to the URL like; http://endpoint?param=value¶m2=value2. You can customize the format using :ref:`format-editor`.
|
||||
|
||||
If you add the prefix `https://` then the device will use SSL when sending data.
|
||||
|
||||
* **Token 2:**
|
||||
|
||||
The token is included in the default format for the HTTP GET url but can be used for any of the formats. For HTTP GET use can use this for an authorization token with for instance ubidots or blynk http api.
|
||||
|
||||
* **Brewfather URL:**
|
||||
|
||||
Endpoint to send data via http to brewfather. Format used :ref:`data-formats-brewfather`
|
||||
|
@ -5,8 +5,8 @@ Data Formats
|
||||
|
||||
.. _data-formats-ispindle:
|
||||
|
||||
iSpindle format
|
||||
===============
|
||||
HTTP Post, iSpindle format
|
||||
==========================
|
||||
|
||||
This is the format used for standard http posts.
|
||||
|
||||
@ -75,6 +75,25 @@ This is the format for Brewfather. See: `Brewfather API docs <https://docs.brewf
|
||||
|
||||
.. _data-formats-influxdb2:
|
||||
|
||||
HTTP Get
|
||||
========
|
||||
|
||||
This is the format added to the URL when using HTTP get
|
||||
|
||||
.. code-block::
|
||||
|
||||
?name=<mdns>,id=<id>,token=<token>&interval=300&temperature=20.1&temp-units=<C|F>&
|
||||
gravity=$1.004&angle=45.5&battery=3.96&rssi=-18&corr-gravity=1.004&gravity-unit=<G|P>&run-time=2.1
|
||||
|
||||
This is the format template used to create the data above.
|
||||
|
||||
.. code-block::
|
||||
|
||||
?name=${mdns}&id=${id}&token=${token2}&interval=${sleep-interval}&temperature=${temp}&
|
||||
temp-units=${temp-unit}&gravity=${gravity}&angle=${angle}&battery=${battery}&rssi=${rssi}&
|
||||
corr-gravity=${corr-gravity}&gravity-unit=${gravity-unit}&run-time=${run-time}
|
||||
|
||||
|
||||
Influx DB v2
|
||||
============
|
||||
|
||||
@ -82,14 +101,17 @@ This is the format for InfluxDB v2
|
||||
|
||||
.. code-block::
|
||||
|
||||
measurement,host=<mdns>,device=<id>,temp-format=<C|F>,gravity-format=SG,gravity=1.0004,corr-gravity=1.0004,angle=45.45,temp=20.1,battery=3.96,rssi=-18
|
||||
measurement,host=<mdns>,device=<id>,temp-format=<C|F>,gravity-format=SG,
|
||||
gravity=1.0004,corr-gravity=1.0004,angle=45.45,temp=20.1,battery=3.96,rssi=-18
|
||||
|
||||
|
||||
This is the format template used to create the json above.
|
||||
|
||||
.. code-block::
|
||||
|
||||
measurement,host=${mdns},device=${id},temp-format=${temp-unit},gravity-format=${gravity-unit} gravity=${gravity},corr-gravity=${corr-gravity},angle=${angle},temp=${temp},battery=${battery},rssi=${rssi}
|
||||
measurement,host=${mdns},device=${id},temp-format=${temp-unit},
|
||||
gravity-format=${gravity-unit} gravity=${gravity},corr-gravity=${corr-gravity},
|
||||
angle=${angle},temp=${temp},battery=${battery},rssi=${rssi}
|
||||
|
||||
|
||||
.. _data-formats-mqtt:
|
||||
@ -130,7 +152,10 @@ This is a format template that is compatible with v0.6. Just replace the `topic`
|
||||
|
||||
.. code-block::
|
||||
|
||||
topic:{"name":"gravmon","ID":"${id}","token":"gravmon","interval": ${sleep-interval},"temperature": ${temp},"temp-units": "${temp-unit}","gravity":${gravity},"angle": ${angle},"battery":${battery},"rssi": ${rssi},"corr-gravity":${corr-gravity},"gravity-unit": "${gravity-unit}","run-time": ${run-time}}|
|
||||
topic:{"name":"gravmon", "ID":"${id}", "token":"gravmon", "interval": ${sleep-interval},
|
||||
"temperature": ${temp}, "temp-units": "${temp-unit}", "gravity":${gravity},
|
||||
"angle": ${angle}, "battery":${battery}, "rssi": ${rssi}, "corr-gravity":${corr-gravity},
|
||||
"gravity-unit": "${gravity-unit}", "run-time": ${run-time}}|
|
||||
|
||||
|
||||
version.json
|
||||
@ -147,7 +172,7 @@ they can be uploaded manually afterwards.
|
||||
"version":"0.7.0",
|
||||
"html": [
|
||||
"index.min.htm",
|
||||
"device.min.htm",
|
||||
"test.min.htm",
|
||||
"config.min.htm",
|
||||
"format.min.htm",
|
||||
"calibration.min.htm",
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 28 KiB |
@ -5,18 +5,18 @@ Releases
|
||||
|
||||
v0.9.0
|
||||
------
|
||||
* Added one http push target that uses HTTP GET. This can be used with ubidots or blynk api's.
|
||||
* Added function to test push targets from configuration page. It will send data and show the return code as a first step.
|
||||
* Experimental release of firmware using an esp32 instead of esp8266
|
||||
* Merged index and device pages into one so that all the needed information is available on the index page.
|
||||
* Removed api for device (/api/device), it's now merged into the /api/status api.
|
||||
* Test function in format editor now uses real data and not fake.
|
||||
* Split push configuration into two sections to make it fit better on smaller devices
|
||||
* Updated WifiManager and DoubleReset libraries
|
||||
* Experimental release of firmware using an esp32 instead of esp8266
|
||||
* Updated esp32 target with littlefs support
|
||||
* Updated esp32 target with BLE send support (it will simulate a tilt)
|
||||
* Corrected PIN for voltage read on ESP32
|
||||
* Mounted esp32 d1 mini mounted to a iSpindle PCB 4.0 (CherryPhilip) which worked fine.
|
||||
|
||||
* BUG: Corrected PIN for voltage read on ESP32
|
||||
* BUG: If using plato and not gravity formula was defined the value was set to null.
|
||||
|
||||
v0.8.0
|
||||
@ -29,7 +29,7 @@ v0.8.0
|
||||
* Added instructions for how to configure integration with Brewspy
|
||||
* Added instructions for how to configure integration with Thingspeak
|
||||
* Added option to do a factory reset via API.
|
||||
* Logging the runtime, how long a measurement take (last 10 are stored). This can be
|
||||
* Added logging of the runtime, how long a measurement take (last 10 are stored). This can be
|
||||
used to check how good the wifi connection is and estimate the lifetime when on battery.
|
||||
Check the device page in the UI for this information.
|
||||
* Refactored code to free up more RAM to make SSL more stable.
|
||||
|
@ -11,6 +11,8 @@
|
||||
"http-push2-h1": "Second",
|
||||
"http-push2-h2": "First",
|
||||
"token": "mytoken",
|
||||
"token2": "mytoken2",
|
||||
"http-push3": "http://192.168.1.10/ispindel",
|
||||
"influxdb2-push": "http://192.168.1.10:8086",
|
||||
"influxdb2-org": "hello",
|
||||
"influxdb2-bucket": "spann",
|
||||
|
@ -2,6 +2,7 @@
|
||||
"id": "7376ef",
|
||||
"http-1": "%7B%22name%22%20%3A%20%22gravmon%22%2C%20%22ID%22%3A%20%22%24%7Bid%7D%22%2C%20%22token%22%20%3A%20%22gravmon%22%2C%20%22interval%22%3A%20%24%7Bsleep%2Dinterval%7D%2C%20%22temperature%22%3A%20%24%7Btemp%7D%2C%20%22temp%2Dunits%22%3A%20%22%24%7Btemp%2Dunit%7D%22%2C%20%22gravity%22%3A%20%24%7Bgravity%7D%2C%20%22angle%22%3A%20%24%7Bangle%7D%2C%20%22battery%22%3A%20%24%7Bbattery%7D%2C%20%22rssi%22%3A%20%24%7Brssi%7D%2C%20%22corr%2Dgravity%22%3A%20%24%7Bcorr%2Dgravity%7D%2C%20%22gravity%2Dunit%22%3A%20%22%24%7Bgravity%2Dunit%7D%22%2C%20%22run%2Dtime%22%3A%20%24%7Brun%2Dtime%7D%20%7D",
|
||||
"http-2": "%7B%22name%22%20%3A%20%22gravmon%22%2C%20%22ID%22%3A%20%22%24%7Bid%7D%22%2C%20%22token%22%20%3A%20%22gravmon%22%2C%20%22interval%22%3A%20%24%7Bsleep%2Dinterval%7D%2C%20%22temperature%22%3A%20%24%7Btemp%7D%2C%20%22temp%2Dunits%22%3A%20%22%24%7Btemp%2Dunit%7D%22%2C%20%22gravity%22%3A%20%24%7Bgravity%7D%2C%20%22angle%22%3A%20%24%7Bangle%7D%2C%20%22battery%22%3A%20%24%7Bbattery%7D%2C%20%22rssi%22%3A%20%24%7Brssi%7D%2C%20%22corr%2Dgravity%22%3A%20%24%7Bcorr%2Dgravity%7D%2C%20%22gravity%2Dunit%22%3A%20%22%24%7Bgravity%2Dunit%7D%22%2C%20%22run%2Dtime%22%3A%20%24%7Brun%2Dtime%7D%20%7D",
|
||||
"http-3": "%7B%22name%22%20%3A%20%22gravmon%22%2C%20%22ID%22%3A%20%22%24%7Bid%7D%22%2C%20%22token%22%20%3A%20%22gravmon%22%2C%20%22interval%22%3A%20%24%7Bsleep%2Dinterval%7D%2C%20%22temperature%22%3A%20%24%7Btemp%7D%2C%20%22temp%2Dunits%22%3A%20%22%24%7Btemp%2Dunit%7D%22%2C%20%22gravity%22%3A%20%24%7Bgravity%7D%2C%20%22angle%22%3A%20%24%7Bangle%7D%2C%20%22battery%22%3A%20%24%7Bbattery%7D%2C%20%22rssi%22%3A%20%24%7Brssi%7D%2C%20%22corr%2Dgravity%22%3A%20%24%7Bcorr%2Dgravity%7D%2C%20%22gravity%2Dunit%22%3A%20%22%24%7Bgravity%2Dunit%7D%22%2C%20%22run%2Dtime%22%3A%20%24%7Brun%2Dtime%7D%20%7D",
|
||||
"influxdb": "measurement%2Chost%3D%24%7Bmdns%7D%2Cdevice%3D%24%7Bid%7D%2Ctemp%2Dformat%3D%24%7Btemp%2Dunit%7D%2Cgravity%2Dformat%3D%24%7Bgravity%2Dunit%7D%20gravity%3D%24%7Bgravity%7D%2Ccorr%2Dgravity%3D%24%7Bcorr%2Dgravity%7D%2Cangle%3D%24%7Bangle%7D%2Ctemp%3D%24%7Btemp%7D%2Cbattery%3D%24%7Bbattery%7D%2Crssi%3D%24%7Brssi%7D%0A",
|
||||
"mqtt": "ispindel%2F%24%7Bmdns%7D%2Ftilt%3A%24%7Bangle%7D%7Cispindel%2F%24%7Bmdns%7D%2Ftemperature%3A%24%7Btemp%7D%7Cispindel%2F%24%7Bmdns%7D%2Ftemp%5Funits%3A%24%7Btemp%2Dunit%7D%7Cispindel%2F%24%7Bmdns%7D%2Fbattery%3A%24%7Bbattery%7D%7Cispindel%2F%24%7Bmdns%7D%2Fgravity%3A%24%7Bgravity%7D%7Cispindel%2F%24%7Bmdns%7D%2Finterval%3A%24%7Bsleep%2Dinterval%7D%7Cispindel%2F%24%7Bmdns%7D%2FRSSI%3A%24%7Brssi%7D%7C"
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
"gravity-format": "G",
|
||||
"temp-c": 12,
|
||||
"temp-f": 32,
|
||||
"sleep-interval": 300,
|
||||
"battery": 3.81,
|
||||
"temp-format": "C",
|
||||
"sleep-mode": false,
|
||||
|
Loading…
Reference in New Issue
Block a user