mirror of
https://github.com/hansaya/BBQMaster.git
synced 2026-07-28 04:05:44 +00:00
init commit
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
.pioenvs
|
||||
.piolibdeps
|
||||
.clang_complete
|
||||
.gcc-flags.json
|
||||
Vendored
+7
File diff suppressed because one or more lines are too long
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Globals
|
||||
*/
|
||||
|
||||
/* Links */
|
||||
a,
|
||||
a:focus,
|
||||
a:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Custom default button */
|
||||
.btn-secondary,
|
||||
.btn-secondary:hover,
|
||||
.btn-secondary:focus {
|
||||
color: #333;
|
||||
text-shadow: none; /* Prevent inheritance from `body` */
|
||||
background-color: #fff;
|
||||
border: .05rem solid #fff;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Base structure
|
||||
*/
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
background-color: #333;
|
||||
}
|
||||
|
||||
body {
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-box;
|
||||
display: flex;
|
||||
-ms-flex-pack: center;
|
||||
-webkit-box-pack: center;
|
||||
justify-content: center;
|
||||
color: #fff;
|
||||
text-shadow: 0 .05rem .1rem rgba(0, 0, 0, .5);
|
||||
box-shadow: inset 0 0 5rem rgba(0, 0, 0, .5);
|
||||
}
|
||||
|
||||
/* .cover-container {
|
||||
max-width: 42em;
|
||||
} */
|
||||
|
||||
|
||||
/*
|
||||
* Header
|
||||
*/
|
||||
.masthead {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.masthead-brand {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.nav-masthead .nav-link {
|
||||
padding: .25rem 0;
|
||||
font-weight: 700;
|
||||
color: rgba(255, 255, 255, .5);
|
||||
background-color: transparent;
|
||||
border-bottom: .25rem solid transparent;
|
||||
}
|
||||
|
||||
.nav-masthead .nav-link:hover,
|
||||
.nav-masthead .nav-link:focus {
|
||||
border-bottom-color: rgba(255, 255, 255, .25);
|
||||
}
|
||||
|
||||
.nav-masthead .nav-link + .nav-link {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.nav-masthead .active {
|
||||
color: #fff;
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
|
||||
@media (min-width: 48em) {
|
||||
.masthead-brand {
|
||||
float: left;
|
||||
}
|
||||
.nav-masthead {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Cover
|
||||
*/
|
||||
.cover {
|
||||
padding: 0 1.5rem;
|
||||
}
|
||||
.cover .btn-lg {
|
||||
padding: .75rem 1.25rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Footer
|
||||
*/
|
||||
.mastfoot {
|
||||
color: rgba(255, 255, 255, .5);
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
/* Regular Styles */
|
||||
@import url(https://fonts.googleapis.com/css?family=Open+Sans);
|
||||
html {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
*,
|
||||
*:before,
|
||||
*:after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
body {
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
color: #4e555f;
|
||||
font-size: 14px;
|
||||
}
|
||||
/* Bar Delays Animation Function */
|
||||
/* Chart Styles */
|
||||
.chart-wrap {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
padding: 10px;
|
||||
/* border: 1px solid #eeeeee; */
|
||||
}
|
||||
.chart-wrap .chart-title {
|
||||
margin-bottom: 10px;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.chart-wrap .row {
|
||||
position: relative;
|
||||
height: 26px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.chart-wrap .bar-wrap {
|
||||
position: relative;
|
||||
background: #d7dbde;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
.chart-wrap .bar-wrap .bar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
background: #f37167;
|
||||
transition: all 1s;
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
.chart-wrap .bar-wrap .bar.in {
|
||||
transform: translateX(0%);
|
||||
}
|
||||
.chart-wrap .row:nth-of-type(1) .bar {
|
||||
transition: 1s 400ms;
|
||||
}
|
||||
.chart-wrap .row:nth-of-type(2) .bar {
|
||||
transition: 1s 600ms;
|
||||
}
|
||||
.chart-wrap .row:nth-of-type(3) .bar {
|
||||
transition: 1s 800ms;
|
||||
}
|
||||
.chart-wrap .row:nth-of-type(4) .bar {
|
||||
transition: 1s 1000ms;
|
||||
}
|
||||
.chart-wrap .row:nth-of-type(5) .bar {
|
||||
transition: 1s 1200ms;
|
||||
}
|
||||
.chart-wrap .row:nth-of-type(6) .bar {
|
||||
transition: 1s 1400ms;
|
||||
}
|
||||
.chart-wrap .row:nth-of-type(7) .bar {
|
||||
transition: 1s 1600ms;
|
||||
}
|
||||
.chart-wrap .label {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 30px;
|
||||
padding-left: 10px;
|
||||
text-align: left;
|
||||
line-height: 26px;
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
z-index: 10;
|
||||
}
|
||||
.chart-wrap .number {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 30px;
|
||||
padding-right: 10px;
|
||||
font-size: 18px;
|
||||
line-height: 26px;
|
||||
font-weight: bold;
|
||||
text-align: right;
|
||||
z-index: 10;
|
||||
}
|
||||
@media screen and (min-width: 800px) {
|
||||
.chart-wrap .row {
|
||||
padding: 0 40px 0 40px;
|
||||
}
|
||||
.chart-wrap .label {
|
||||
text-align: right;
|
||||
padding-left: 0;
|
||||
}
|
||||
.chart-wrap .number {
|
||||
text-align: left;
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Battery indicator*/
|
||||
#wrapper { width:200px;}
|
||||
.battery2 {
|
||||
position: relative;
|
||||
display: block;
|
||||
background: #ffffff;
|
||||
width: 10px;
|
||||
height: 28px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.battery2 {
|
||||
margin-top:48px;
|
||||
background: rgb(157,213,58); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(157,213,58,1) 0%, rgba(161,213,79,1) 50%, rgba(128,194,23,1) 51%, rgba(124,188,10,1) 100%);
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(157,213,58,1)), color-stop(50%,rgba(161,213,79,1)), color-stop(51%,rgba(128,194,23,1)), color-stop(100%,rgba(124,188,10,1)));
|
||||
background: -webkit-linear-gradient(top, rgba(157,213,58,1) 0%,rgba(161,213,79,1) 50%,rgba(128,194,23,1) 51%,rgba(124,188,10,1) 100%);
|
||||
background: -o-linear-gradient(top, rgba(157,213,58,1) 0%,rgba(161,213,79,1) 50%,rgba(128,194,23,1) 51%,rgba(124,188,10,1) 100%);
|
||||
background: -ms-linear-gradient(top, rgba(157,213,58,1) 0%,rgba(161,213,79,1) 50%,rgba(128,194,23,1) 51%,rgba(124,188,10,1) 100%);
|
||||
background: linear-gradient(to bottom, rgba(157,213,58,1) 0%,rgba(161,213,79,1) 50%,rgba(128,194,23,1) 51%,rgba(124,188,10,1) 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#9dd53a', endColorstr='#7cbc0a',GradientType=0 );
|
||||
}
|
||||
|
||||
.battery2:before {
|
||||
content: "";
|
||||
display: block;
|
||||
background: transparent;
|
||||
border: 6px solid #ffffff;
|
||||
margin: -12px;
|
||||
width: 85px;
|
||||
height: 40px;
|
||||
position: absolute;
|
||||
border-radius: 2px;
|
||||
-moz-box-shadow: 0 0 5px 5px #888;
|
||||
-webkit-box-shadow: 0 0 5px 5px#888;
|
||||
box-shadow: -2px 0 5px 2px #222;
|
||||
z-index:2000;
|
||||
}
|
||||
|
||||
.battery2:after {
|
||||
content: "";
|
||||
display: block;
|
||||
background: #ffffff;
|
||||
border: 6px solid #ffffff;
|
||||
margin: 0px 80px;
|
||||
width: 6px;
|
||||
height: 16px;
|
||||
position: absolute;
|
||||
border-radius: 2px;
|
||||
-moz-box-shadow: 0 0 5px 5px #888;
|
||||
-webkit-box-shadow: 0 0 5px 5px #888;
|
||||
box-shadow: 2px 0 5px 2px #222;
|
||||
z-index:0;
|
||||
}
|
||||
|
||||
@-webkit-keyframes charging2 {
|
||||
from { width: 0px; background: #f00; }
|
||||
to { width: 72px; background: #0f0; }
|
||||
}
|
||||
|
||||
@-webkit-keyframes showcharging {
|
||||
from { width: 0px; background: #f00; }
|
||||
to { width: 20px; background: #0f0; }
|
||||
}
|
||||
|
||||
.charging2 {
|
||||
-webkit-animation: charging2 20s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.showcharging {
|
||||
-webkit-animation: showcharging 20s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.charging_txt {
|
||||
font-family: arial, helvetica, sans-serif;
|
||||
font-weight:bold;
|
||||
font-style:italic;
|
||||
text-align:center;
|
||||
clear:both;
|
||||
color:#fff;
|
||||
text-shadow:0 2px #000;
|
||||
}
|
||||
|
||||
@-webkit-keyframes glow {
|
||||
from { opacity:0;}
|
||||
to { opacity:1;}
|
||||
}
|
||||
|
||||
.glow {
|
||||
-webkit-animation: glow 3s ease-in-out infinite;
|
||||
-webkit-animation-direction: alternate;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 6.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
+453
@@ -0,0 +1,453 @@
|
||||
<!DOCTYPE html>
|
||||
<html charset="UTF-8">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<link rel="stylesheet" href="/css/custom.css">
|
||||
<link href="/css/bootstrap.min.css" rel="stylesheet" title="main">
|
||||
<link rel="stylesheet" href="/css/cover.css">
|
||||
<!-- <link href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.7/superhero/bootstrap.min.css" rel="stylesheet" title="main"> -->
|
||||
<!-- <script src="//cdn.rawgit.com/Mikhus/canvas-gauges/gh-pages/download/2.1.5/all/gauge.min.js"></script> -->
|
||||
<title>BBQ Master</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container d-flex h-100 p-3 mx-auto flex-column">
|
||||
|
||||
<header class="masthead">
|
||||
<div class="inner">
|
||||
<h3 class="masthead-brand">BBQ Master</h3>
|
||||
<nav class="nav nav-masthead justify-content-center navbar-expand-lg tabs" id="tab">
|
||||
<a class="nav-link active" href="#tab_mesures" data-toggle="tab">Home</a>
|
||||
<a class="nav-link" href="#tab_configuration" data-toggle="tab">Settings</a>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main role="main" class="container">
|
||||
<!-- <div class="row">
|
||||
<div class="col-md-4">
|
||||
<h1>BBQ Master</h1>
|
||||
</div>
|
||||
<div class="col-md-4 pull-right" id="wrapper">
|
||||
<div class="battery2 showcharging"></div>
|
||||
</div>
|
||||
</div> -->
|
||||
<!-- <div class="row"> -->
|
||||
<!-- <ul class="nav nav-tabs" id="tab">
|
||||
<li class="active"><a href="#tab_mesures" data-toggle="tab">Dashboard</a></li>
|
||||
<li><a href="#tab_configuration" data-toggle="tab">Configuration</a></li>
|
||||
</ul> -->
|
||||
<div class="content position-relative">
|
||||
<div class="tab-pane fade in active show" id="tab_mesures">
|
||||
<!-- <h2>Smoker Controller</h2> -->
|
||||
<!-- <div class="alert alert-danger" role="alert" style="display:none;">
|
||||
<strong>Oh snap!</strong> Running out of wood!
|
||||
</div> -->
|
||||
<div class="row bg-dark rounded p-3 p-md-5 m-md-3 text-center">
|
||||
<ul class="nav nav-pills">
|
||||
<li><a href="#">
|
||||
<div class="span badge pull-right" id="batvoltage">-</div>Battery Voltage</a></li>
|
||||
<li><a href="#">
|
||||
<div class="span badge pull-right" id="sensor0">-</div>Sen 1</a></li>
|
||||
<li><a href="#">
|
||||
<div class="span badge pull-right" id="sensor1">-</div>Sen 2</a></li>
|
||||
<li><a href="#">
|
||||
<div class="span badge pull-right" id="sensor2">-</div>Sen 3</a></li>
|
||||
<li><a href="#">
|
||||
<div class="span badge pull-right" id="sensor3">-</div>Sen 4</a></li>
|
||||
<li><a href="#">
|
||||
<div class="span badge pull-right" id="sensor4">-</div>Sen 5</a></li>
|
||||
<li><a href="#">
|
||||
<div class="span badge pull-right" id="sensor5">-</div>Sen 6</a></li>
|
||||
<li><a href="#">
|
||||
<div class="span badge pull-right" id="sensor6">-</div>Sen 7</a></li>
|
||||
<li><a href="#">
|
||||
<div class="span badge pull-right" id="sensor7">-</div>Sen 8</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- <div class="row "> -->
|
||||
<div class="chart-wrap text-center rounded p-3 p-md-5 m-md-3">
|
||||
<!-- <div class="chart-title">
|
||||
BBQ Tempurature
|
||||
</div> -->
|
||||
<div id="dashboard-stats" class="chart bars-horizontal brand-primary">
|
||||
<div class="row" id="sensorBar0">
|
||||
<span class="label">Interest 1</span>
|
||||
<div class="bar-wrap">
|
||||
<div class="bar" data-value="62"></div>
|
||||
</div>
|
||||
<span class="number">62</span>
|
||||
</div>
|
||||
<div class="row" id="sensorBar1">
|
||||
<span class="label">Interest 2</span>
|
||||
<div class="bar-wrap">
|
||||
<div class="bar" data-value="35"></div>
|
||||
</div>
|
||||
<span class="number">35</span>
|
||||
</div>
|
||||
<div class="row" id="sensorBar2">
|
||||
<span class="label">Interest 3</span>
|
||||
<div class="bar-wrap">
|
||||
<div class="bar" data-value="18"></div>
|
||||
</div>
|
||||
<span class="number">18</span>
|
||||
</div>
|
||||
<div class="row" id="sensorBar3">
|
||||
<span class="label">Interest 4</span>
|
||||
<div class="bar-wrap">
|
||||
<div class="bar" data-value="13"></div>
|
||||
</div>
|
||||
<span class="number">13</span>
|
||||
</div>
|
||||
<div class="row" id="sensorBar4">
|
||||
<span class="label">Interest 5</span>
|
||||
<div class="bar-wrap">
|
||||
<div class="bar" data-value="8"></div>
|
||||
</div>
|
||||
<span class="number">8</span>
|
||||
</div>
|
||||
<div class="row" id="sensorBar5">
|
||||
<span class="label">Interest 6</span>
|
||||
<div class="bar-wrap">
|
||||
<div class="bar" data-value="5"></div>
|
||||
</div>
|
||||
<span class="number">5</span>
|
||||
</div>
|
||||
<div class="row" id="sensorBar6">
|
||||
<span class="label">Interest 7</span>
|
||||
<div class="bar-wrap">
|
||||
<div class="bar" data-value="2"></div>
|
||||
</div>
|
||||
<span class="number">2</span>
|
||||
</div>
|
||||
<div class="row" id="sensorBar7">
|
||||
<span class="label">Interest 8</span>
|
||||
<div class="bar-wrap">
|
||||
<div class="bar" data-value="9"></div>
|
||||
</div>
|
||||
<span class="number">9</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- </div> -->
|
||||
|
||||
<div class="row col-xs-12">
|
||||
<!-- style="display: block; width: 701px; height: 350px;" -->
|
||||
<canvas id="myChart" class="chartjs-render-monitor" ></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="tab_configuration">
|
||||
<h2>Configuration </h2>
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-default" id="labelTheme">Theme</button>
|
||||
<button class="btn btn-default dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="change-style-menu-item" href="#" rel="bootstrap">Boostrap</a></li>
|
||||
<li><a class="change-style-menu-item" href="#" rel="cerulean">Cerulean</a></li>
|
||||
<li><a class="change-style-menu-item" href="#" rel="cosmo">Cosmo</a></li>
|
||||
<li><a class="change-style-menu-item" href="#" rel="cyborg">Cyborg</a></li>
|
||||
<li><a class="change-style-menu-item" href="#" rel="darkly">Darkly</a></li>
|
||||
<li><a class="change-style-menu-item" href="#" rel="flatly">Flatly</a></li>
|
||||
<li><a class="change-style-menu-item" href="#" rel="journal">Journal</a></li>
|
||||
<li><a class="change-style-menu-item" href="#" rel="lumen">Lumen</a></li>
|
||||
<li><a class="change-style-menu-item" href="#" rel="paper">Paper</a></li>
|
||||
<li><a class="change-style-menu-item" href="#" rel="readable">Readable</a></li>
|
||||
<li><a class="change-style-menu-item" href="#" rel="sandstone">Sandstone</a></li>
|
||||
<li><a class="change-style-menu-item" href="#" rel="simplex">Simplex</a></li>
|
||||
<li><a class="change-style-menu-item" href="#" rel="slate">Slate</a></li>
|
||||
<li><a class="change-style-menu-item" href="#" rel="spacelab">Spacelab</a></li>
|
||||
<li><a class="change-style-menu-item" href="#" rel="superhero">Superhero</a></li>
|
||||
<li><a class="change-style-menu-item" href="#" rel="united">United</a></li>
|
||||
<li><a class="change-style-menu-item" href="#" rel="yeti">Yeti </a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- </div> -->
|
||||
</main>
|
||||
<footer class="page-footer font-small">
|
||||
<div class="col-xs-2 col-md-2"><img src="/img/logo.png" width="30" height="30"></div>
|
||||
<div class="col-xs-5 col-md-5">
|
||||
<p><a href="https://github.com/hansaya/BBQ_MASTER">Github</a></p>
|
||||
</div>
|
||||
<div class="col-xs-5 col-md-5">
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="/js/jquery.min.js"></script>
|
||||
<script src="/js/popper.min.js"></script>
|
||||
<script src="/js/bootstrap.min.js"></script>
|
||||
<script src="/js/moment.min.js"></script>
|
||||
<script src="/js/Chart.min.js"></script>
|
||||
|
||||
<script>
|
||||
var Timer_UdpateMesures;
|
||||
var tab_pane = '#tab_mesures';
|
||||
var tabRefresh = false;
|
||||
|
||||
//New front page grapgh
|
||||
var canvas = document.getElementById('myChart'),
|
||||
ctx = canvas.getContext('2d'),
|
||||
startingData = {
|
||||
labels: [],
|
||||
datasets: []
|
||||
};
|
||||
// Reduce the animation steps for demo clarity.
|
||||
var liveChart = new Chart(ctx, {
|
||||
type: "line",
|
||||
data: startingData,
|
||||
animationSteps: 15,
|
||||
borderColor: 'rgba(244, 245, 244, 0.1)',
|
||||
options: {
|
||||
title: {
|
||||
text: 'Temp Scale'
|
||||
},
|
||||
scales: {
|
||||
xAxes: [{
|
||||
type: 'time',
|
||||
time: {
|
||||
displayFormats: {
|
||||
quarter: 'h:mm:ss a'
|
||||
}
|
||||
},
|
||||
distribution: 'linear',
|
||||
scaleLabel: {
|
||||
display: true,
|
||||
labelString: 'Date'
|
||||
},
|
||||
ticks: {
|
||||
fontColor : "#F4F5F4"
|
||||
}
|
||||
}],
|
||||
yAxes: [{
|
||||
scaleLabel: {
|
||||
display: true,
|
||||
labelString: 'Fahrenheit'
|
||||
},
|
||||
ticks: {
|
||||
fontColor : "#F4F5F4"
|
||||
}
|
||||
}]
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
function addGraphData(chart, name, newEntry) {
|
||||
|
||||
var foundSen = false;
|
||||
chart.data.datasets.forEach((dataset) => {
|
||||
if (dataset.label == name)
|
||||
{
|
||||
dataset.data.push(newEntry);
|
||||
foundSen = true;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
if (!foundSen)
|
||||
{
|
||||
var colorR = Math.floor((Math.random() * 256));
|
||||
var colorG = Math.floor((Math.random() * 256));
|
||||
var colorB = Math.floor((Math.random() * 256));
|
||||
|
||||
chart.data.datasets.push ({
|
||||
fill: false,
|
||||
label: name,
|
||||
backgroundColor: "rgba("+colorR+","+colorG+","+colorB+",1.00)",
|
||||
borderColor: "rgba("+colorR+","+colorG+","+colorB+",1.00)",
|
||||
data: []
|
||||
});
|
||||
chart.data.datasets[chart.data.datasets.length - 1].data.push(newEntry);
|
||||
}
|
||||
chart.update();
|
||||
}
|
||||
|
||||
// Update the history at start
|
||||
updateTheHistory ();
|
||||
|
||||
// Update the grapgh at start
|
||||
updateBarGrapgh ();
|
||||
|
||||
setInterval(updateBarGrapgh, 5000); //60000 MS == 1 minutes
|
||||
|
||||
function updateTheHistory ()
|
||||
{
|
||||
console.log("Getting history!");
|
||||
$.getJSON('/history.json', function(json){
|
||||
|
||||
// Data line chart
|
||||
for ( var i = 0; i < json.hist.length; i++ ) {
|
||||
// Update the time label
|
||||
liveChart.data.labels.push(new Date(json.hist[i].t * 1000));
|
||||
|
||||
for ( var j = 0; j < json.hist[i].sensors.length; j++ ) {
|
||||
// Update the grapgh the new data
|
||||
addGraphData (liveChart, json.hist[i].sensors[j].n, {t: new Date(json.hist[i].t * 1000), y: json.hist[i].sensors[j].v});
|
||||
}
|
||||
}
|
||||
|
||||
}).fail(function(err){
|
||||
console.log("err getJSON history.json "+JSON.stringify(err));
|
||||
});
|
||||
}
|
||||
|
||||
function updateBarGrapgh ()
|
||||
{
|
||||
if (tab_pane=='#tab_mesures')
|
||||
{
|
||||
// console.log("Updating the gauge");
|
||||
$.getJSON('/measures.json', function(data){
|
||||
// Update the time label
|
||||
liveChart.data.labels.push(new Date(data.t * 1000));
|
||||
|
||||
for ( var i = 0; i < data.sensors.length; i++ ) {
|
||||
if (data.sensors[i].i == 1)
|
||||
{
|
||||
$('#sensor'+ i).html("<b>" + data.sensors[i].v + "°F </b>");
|
||||
document.getElementById('sensorBar' + i).getElementsByClassName('bar-wrap')[0].getElementsByClassName('bar')[0].setAttribute ('data-value', data.sensors[i].v);
|
||||
document.getElementById('sensorBar' + i).getElementsByClassName('number')[0].innerText = data.sensors[i].v;
|
||||
|
||||
// Update the grapgh the new data
|
||||
addGraphData (liveChart, data.sensors[i].n, {t: new Date(data.t * 1000), y: data.sensors[i].v});
|
||||
|
||||
if (document.getElementById('sensorBar' + i).style.display == "none")
|
||||
{
|
||||
document.getElementById('sensorBar' + i).style.display = "block";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$('#sensor'+ i).html("<b> N/A </b>");
|
||||
// Hide the bar element if value is invalid
|
||||
document.getElementById('sensorBar' + i).style.display = "none";
|
||||
}
|
||||
$('#batvoltage').html("<b>" + data.bat + "v </b>");
|
||||
|
||||
// TempValues.push(data.sensors[i].v);
|
||||
document.getElementById('sensorBar' + i).getElementsByClassName('label')[0].innerText = data.sensors[i].n;
|
||||
}
|
||||
|
||||
// Update the Fancy grapgh
|
||||
generateBarGraph('#dashboard-stats');
|
||||
}).fail(function(err){
|
||||
console.log("err getJSON measures.json "+JSON.stringify(err));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function generateBarGraph(wrapper) {
|
||||
// Set Up Values Array
|
||||
var values = [];
|
||||
|
||||
// Get Values and save to Array
|
||||
$(wrapper + ' .bar').each(function(index, el) {
|
||||
if ($(this).closest(".row").is(":visible"))
|
||||
{
|
||||
values.push($(this).attr('data-value'));
|
||||
}
|
||||
});
|
||||
|
||||
// Get Max Value From Array
|
||||
var max_value = Math.max.apply(Math, values)+10;
|
||||
console.log ('Max value ' + max_value);
|
||||
// Set width of bar to percent of max value
|
||||
$(wrapper + ' .bar').each(function(index, el) {
|
||||
var bar = $(this),
|
||||
value = bar.attr('data-value'),
|
||||
percent = Math.ceil((value / max_value) * 100);
|
||||
|
||||
// Set Width & Add Class
|
||||
bar.width(percent + '%');
|
||||
bar.addClass('in');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$(".tabs a[title='tab_mesures']").click()
|
||||
|
||||
$('a[data-toggle=\"tab\"]').on('shown.bs.tab', function (e) {
|
||||
//On supprime tous les timers lorsqu'on change d'onglet
|
||||
clearTimeout(Timer_UdpateMesures);
|
||||
tab_pane = $(e.target).attr("href")
|
||||
console.log('activated ' + tab_pane );
|
||||
// tabRefresh = true;
|
||||
|
||||
window.dispatchEvent(new Event('resize'));
|
||||
// IE10, Firefox, Chrome, etc.
|
||||
if (history.pushState)
|
||||
window.history.pushState(null, null, tab_pane);
|
||||
else
|
||||
window.location.hash = tab_pane;
|
||||
});
|
||||
|
||||
|
||||
// Changement du theme - Change current theme
|
||||
// Adapté de - Adapted from : https://wdtz.org/bootswatch-theme-selector.html
|
||||
var supports_storage = supports_html5_storage();
|
||||
if (supports_storage) {
|
||||
var theme = localStorage.theme;
|
||||
console.log("Recharge le theme " + theme);
|
||||
if (theme) {
|
||||
// set_theme(get_themeUrl(theme));
|
||||
}
|
||||
}
|
||||
|
||||
// Nouveau theme sélectionne - New theme selected
|
||||
jQuery(function($){
|
||||
$('body').on('click', '.change-style-menu-item', function() {
|
||||
var theme_name = $(this).attr('rel');
|
||||
console.log("Change theme " + theme_name);
|
||||
var theme_url = get_themeUrl(theme_name);
|
||||
console.log("URL theme : " + theme_url);
|
||||
set_theme(theme_url);
|
||||
});
|
||||
});
|
||||
|
||||
// Recupere l'adresse du theme - Get theme URL
|
||||
function get_themeUrl(theme_name){
|
||||
$('#labelTheme').html("Thème : " + theme_name);
|
||||
var url_theme = "";
|
||||
if ( theme_name === "bootstrap" ) {
|
||||
url_theme = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css";
|
||||
} else {
|
||||
url_theme = "https://maxcdn.bootstrapcdn.com/bootswatch/3.3.7/" + theme_name + "/bootstrap.min.css";
|
||||
}
|
||||
if (supports_storage) {
|
||||
// Enregistre le theme sélectionné en local - save into the local database the selected theme
|
||||
localStorage.theme = theme_name;
|
||||
}
|
||||
return url_theme;
|
||||
}
|
||||
|
||||
// Applique le thème - Apply theme
|
||||
function set_theme(theme_url) {
|
||||
$('link[title="main"]').attr('href', theme_url);
|
||||
}
|
||||
|
||||
// Stockage local disponible ? - local storage available ?
|
||||
function supports_html5_storage(){
|
||||
try {
|
||||
return 'localStorage' in window && window['localStorage'] !== null;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<!-- TODO -->
|
||||
<!--
|
||||
* Stick to one theme
|
||||
* Be able to set the Tempurature probe names
|
||||
* Have everything surved under local storage #done
|
||||
* Select a proper output for sensor data #done
|
||||
* Battery output indication
|
||||
* Be able to set a warninig level -> push that to MQTT (min and max values)
|
||||
* -->
|
||||
Vendored
+10
File diff suppressed because one or more lines are too long
Vendored
+7
File diff suppressed because one or more lines are too long
Vendored
+2
File diff suppressed because one or more lines are too long
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
+5
File diff suppressed because one or more lines are too long
@@ -0,0 +1,46 @@
|
||||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; http://docs.platformio.org/page/projectconf.html
|
||||
[env:myenv]
|
||||
platform = espressif32
|
||||
board = featheresp32
|
||||
framework = arduino
|
||||
|
||||
; Library options
|
||||
lib_deps =
|
||||
OneWire
|
||||
; WebServer
|
||||
DallasTemperature
|
||||
; NtpClientLib
|
||||
AsyncMqttClient
|
||||
Time
|
||||
; https://github.com/gmag11/NtpClient.git
|
||||
https://github.com/mcspr/NtpClient.git#platformio-manifest
|
||||
https://github.com/adafruit/Adafruit_ADS1X15.git
|
||||
https://github.com/me-no-dev/ESPAsyncWebServer.git
|
||||
https://github.com/alanswx/ESPAsyncWiFiManager.git
|
||||
https://github.com/bblanchon/ArduinoJson.git
|
||||
https://github.com/Phillaf/Arduino-SimpleList.git
|
||||
|
||||
; lib_ignore=Time
|
||||
|
||||
; upload_flags = --spiffs
|
||||
upload_protocol = espota
|
||||
upload_speed = 921600
|
||||
upload_port = COM7
|
||||
upload_port = 172.168.1.75
|
||||
;upload_port = 172.168.1.89
|
||||
|
||||
; [env:nodemcuv2_spiffs]
|
||||
; platform = espressif8266
|
||||
; framework = arduino
|
||||
; board = nodemcuv2
|
||||
; ; ; upload_flags = --spiffs
|
||||
; targets = uploadfs
|
||||
; upload_port = 172.168.1.29
|
||||
@@ -0,0 +1,442 @@
|
||||
|
||||
#include <Adafruit_ADS1015.h>
|
||||
#include <DNSServer.h>
|
||||
#include <OneWire.h>
|
||||
// #include <WebServer.h>
|
||||
// #include <WiFiManager.h>
|
||||
//needed for library
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <ESPAsyncWiFiManager.h> //https://github.com/tzapu/WiFiManager
|
||||
|
||||
#include <Wire.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <SimpleList.h>
|
||||
#include "DallasTemperature.h"
|
||||
|
||||
// Remote firmware update
|
||||
#include <ArduinoOTA.h>
|
||||
|
||||
#include <FS.h>
|
||||
#include <NtpClientLib.h>
|
||||
#include <Time.h>
|
||||
#include <TimeLib.h>
|
||||
#include <WiFi.h>
|
||||
#include "SPIFFS.h"
|
||||
|
||||
#define DEBUG
|
||||
|
||||
#define I2C_SDA_PIN 23
|
||||
#define I2C_SCL_PIN 22
|
||||
#define BATTERY_V_PIN 35
|
||||
|
||||
#define BAT_RATIO 0.0017240449438202
|
||||
#define NTC_MAX_ADC 27550.00
|
||||
#define NTC_REF_RES 62000
|
||||
#define NTC_SMP_TMP 25.81
|
||||
#define NTC_SMP_RES 52250
|
||||
#define NTC_BCOEFFICIENT 4200 //3950
|
||||
#define HIST_SIZE 20
|
||||
#define HIST_INT 5000
|
||||
#define SENSOR_READ_INT 1500
|
||||
#define NTP_RETRY_INT 5000
|
||||
|
||||
Adafruit_ADS1115 g_ads (0x49); /* Use this for the 16-bit version */
|
||||
AsyncWebServer g_server (80);
|
||||
OneWire g_oneWireTemp (17);
|
||||
DallasTemperature g_thermoCouples (&g_oneWireTemp);
|
||||
DNSServer dns;
|
||||
|
||||
// MAX31850KATB+-ND
|
||||
DeviceAddress g_sensor1 = {0x3B, 0x45, 0x21, 0x18, 0x00, 0x00, 0x00, 0x2D};
|
||||
DeviceAddress g_sensor2 = {0x3B, 0xF1, 0x22, 0x18, 0x00, 0x00, 0x00, 0xB8};
|
||||
DeviceAddress g_sensor3 = {0x3B, 0xF3, 0x22, 0x18, 0x00, 0x00, 0x00, 0xD6};
|
||||
DeviceAddress g_sensor4 = {0x3B, 0x43, 0x21, 0x18, 0x00, 0x00, 0x00, 0x9F};
|
||||
|
||||
unsigned long g_currentMillis = 0;
|
||||
unsigned long g_prevMilForInputRead = 0;
|
||||
unsigned long g_histPreviousMillis = 0;
|
||||
unsigned long g_prevMilForNTPRetry = 0;
|
||||
double g_batteryVoltage = 0;
|
||||
bool g_ntpError = false;
|
||||
short g_maxWorkingSensors = 0;
|
||||
|
||||
// Representation of one temperature probe
|
||||
struct Sensor
|
||||
{
|
||||
bool m_ind;
|
||||
double m_tempF;
|
||||
String m_name;
|
||||
|
||||
public:
|
||||
Sensor (bool ind, double tempF, String name) : m_ind (ind), m_tempF (tempF), m_name (name) {}
|
||||
Sensor () : m_ind (false), m_tempF (0), m_name ("N/A") {}
|
||||
};
|
||||
|
||||
// Data point completed with multiple probes
|
||||
struct DataPoint
|
||||
{
|
||||
int m_time;
|
||||
Sensor m_sensors[8];
|
||||
};
|
||||
|
||||
// Current data set
|
||||
DataPoint g_lastSenUpdate;
|
||||
|
||||
// Saving the history for the histogram
|
||||
SimpleList<DataPoint> g_tempHist;
|
||||
|
||||
// Flag for saving data from wifi portal
|
||||
bool g_shouldSaveConfig = false;
|
||||
|
||||
// Setup OTA
|
||||
void setupOTA(char *hostname)
|
||||
{
|
||||
// Config OTA updates
|
||||
ArduinoOTA.onStart([]() { Serial.println("Start"); });
|
||||
ArduinoOTA.onEnd([]() { Serial.println("\nEnd"); });
|
||||
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { Serial.printf("Progress: %u%%\r", (progress / (total / 100))); });
|
||||
ArduinoOTA.onError([](ota_error_t error) {
|
||||
Serial.printf("Error[%u]: ", error);
|
||||
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
|
||||
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
|
||||
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
|
||||
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
|
||||
else if (error == OTA_END_ERROR) Serial.println("End Failed");
|
||||
});
|
||||
ArduinoOTA.setHostname(hostname);
|
||||
ArduinoOTA.begin();
|
||||
}
|
||||
|
||||
// Call back for saving the config.
|
||||
void SaveConfigCallback () {
|
||||
Serial.println("Should save config");
|
||||
g_shouldSaveConfig = true;
|
||||
}
|
||||
|
||||
// Manages wifi portal
|
||||
void ManageWifi (bool reset_config = false)
|
||||
{
|
||||
// WiFiManager wifiManager;
|
||||
AsyncWiFiManager wifiManager(&g_server, &dns);
|
||||
wifiManager.setConnectTimeout(60);
|
||||
wifiManager.setConfigPortalTimeout(60);
|
||||
wifiManager.setMinimumSignalQuality(10);
|
||||
wifiManager.setSaveConfigCallback(&SaveConfigCallback);
|
||||
|
||||
if (reset_config)
|
||||
wifiManager.startConfigPortal("BBQ_Master");
|
||||
else
|
||||
wifiManager.autoConnect("BBQ_Master"); // This will hold the connection till it get a connection
|
||||
|
||||
if (g_shouldSaveConfig)
|
||||
{
|
||||
g_shouldSaveConfig = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate NTC temp using steinhart equation
|
||||
float NTCTemp (int16_t adcValue)
|
||||
{
|
||||
if (adcValue < NTC_MAX_ADC)
|
||||
{
|
||||
float steinhart;
|
||||
// Resistance calculation
|
||||
steinhart = (NTC_MAX_ADC / adcValue) - 1;
|
||||
steinhart = NTC_REF_RES / steinhart;
|
||||
|
||||
// Rest of the steinhart equation
|
||||
steinhart = steinhart / NTC_SMP_RES;
|
||||
steinhart = log(steinhart); // ln(R/Ro)
|
||||
steinhart /= NTC_BCOEFFICIENT; // 1/B * ln(R/Ro)
|
||||
steinhart += 1.0 / (NTC_SMP_TMP + 273.15); // + (1/To)
|
||||
steinhart = 1.0 / steinhart; // Invert
|
||||
steinhart -= 273.15;
|
||||
return DallasTemperature::toFahrenheit(steinhart);
|
||||
}
|
||||
else
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
// Check whether temperature is valid.
|
||||
bool IsValidTemp (float temp)
|
||||
{
|
||||
if (temp <= 32.0 || temp > 1000.00)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
// Read all the sensors
|
||||
void ReadSensors ()
|
||||
{
|
||||
|
||||
int16_t adc0, adc1, adc2, adc3;
|
||||
float ntc0, ntc1, ntc2, ntc3;
|
||||
// NTC readings
|
||||
adc0 = g_ads.readADC_SingleEnded (0);
|
||||
adc1 = g_ads.readADC_SingleEnded (1);
|
||||
adc2 = g_ads.readADC_SingleEnded (2);
|
||||
adc3 = g_ads.readADC_SingleEnded (3);
|
||||
|
||||
ntc0 = NTCTemp (adc0);
|
||||
ntc1 = NTCTemp (adc1);
|
||||
ntc2 = NTCTemp (adc2);
|
||||
ntc3 = NTCTemp (adc3);
|
||||
|
||||
float tcp0, tcp1, tcp2, tcp3;
|
||||
tcp0 = g_thermoCouples.getTempF (g_sensor1);
|
||||
tcp1 = g_thermoCouples.getTempF (g_sensor2);
|
||||
tcp2 = g_thermoCouples.getTempF (g_sensor3);
|
||||
tcp3 = g_thermoCouples.getTempF (g_sensor4);
|
||||
|
||||
long int tps = now ();
|
||||
if (tps > 0)
|
||||
{
|
||||
g_lastSenUpdate.m_time = tps;
|
||||
g_lastSenUpdate.m_sensors[0] = Sensor (IsValidTemp (ntc0), ntc0, "NTC1");
|
||||
g_lastSenUpdate.m_sensors[1] = Sensor (IsValidTemp (ntc1), ntc1, "NTC2");
|
||||
g_lastSenUpdate.m_sensors[2] = Sensor (IsValidTemp (ntc2), ntc2, "NTC3");
|
||||
g_lastSenUpdate.m_sensors[3] = Sensor (IsValidTemp (ntc3), ntc3, "NTC4");
|
||||
|
||||
// Thermocouple readings
|
||||
g_lastSenUpdate.m_sensors[4] = Sensor (IsValidTemp (tcp0), tcp0, "TC1");
|
||||
g_lastSenUpdate.m_sensors[5] = Sensor (IsValidTemp (tcp1), tcp1, "TC2");
|
||||
g_lastSenUpdate.m_sensors[6] = Sensor (IsValidTemp (tcp2), tcp2, "TC3");
|
||||
g_lastSenUpdate.m_sensors[7] = Sensor (IsValidTemp (tcp3), tcp3, "TC4");
|
||||
}
|
||||
|
||||
g_batteryVoltage = analogRead (BATTERY_V_PIN) * BAT_RATIO;
|
||||
|
||||
// Request thermo couple data
|
||||
g_thermoCouples.setWaitForConversion(false); // makes it async
|
||||
g_thermoCouples.requestTemperatures();
|
||||
g_thermoCouples.setWaitForConversion(true);
|
||||
|
||||
#ifdef DEBUG
|
||||
Serial.print ("AIN0: ");
|
||||
Serial.println (adc0);
|
||||
// Serial.print (" v: ");
|
||||
// Serial.println ((adc0 * 0.125) / 1000);
|
||||
// Serial.print ("AIN1: ");
|
||||
// Serial.print (adc1);
|
||||
// Serial.print (" v: ");
|
||||
// Serial.println ((adc1 * 0.125) / 1000);
|
||||
|
||||
Serial.print ("Temp NTC 0 F: ");
|
||||
Serial.println (g_lastSenUpdate.m_sensors[0].m_tempF);
|
||||
Serial.print ("Temp NTC 1 F: ");
|
||||
Serial.println (g_lastSenUpdate.m_sensors[1].m_tempF);
|
||||
Serial.print ("Temp NTC 2 F: ");
|
||||
Serial.println (g_lastSenUpdate.m_sensors[2].m_tempF);
|
||||
Serial.print ("Temp NTC 3 F: ");
|
||||
Serial.println (g_lastSenUpdate.m_sensors[3].m_tempF);
|
||||
|
||||
// Serial.print ("AIN2: ");
|
||||
// Serial.print (adc2);
|
||||
// Serial.print (" v: ");
|
||||
// Serial.println ((adc2 * 0.125) / 1000);
|
||||
// Serial.print ("AIN3: ");
|
||||
// Serial.print (adc3);
|
||||
// Serial.print (" v: ");
|
||||
// Serial.println ((adc3 * 0.125) / 1000);
|
||||
// Serial.println (" ");
|
||||
|
||||
Serial.print ("Temp 0 F: ");
|
||||
Serial.println (tcp0);
|
||||
Serial.print ("Temp 1 F: ");
|
||||
Serial.println (tcp1);
|
||||
Serial.print ("Temp 2 F: ");
|
||||
Serial.println (tcp2);
|
||||
Serial.print ("Temp 3 F: ");
|
||||
Serial.println (tcp3);
|
||||
|
||||
// Serial.print ("battery voltage: ");
|
||||
// Serial.print (g_batteryVoltage);
|
||||
// Serial.println ("v");
|
||||
#endif
|
||||
}
|
||||
|
||||
// Send the last sensor data reading in json format.
|
||||
void SendMeasures (AsyncWebServerRequest *request)
|
||||
{
|
||||
Serial.println ("Sending measurements!");
|
||||
DynamicJsonDocument json(1024); // Current JSON static buffer
|
||||
// JsonObject& root = jsonBuffer.createObject ();
|
||||
json["bat"] = g_batteryVoltage;
|
||||
json["t"] = g_lastSenUpdate.m_time;
|
||||
JsonArray sensors = json.createNestedArray ("sensors");
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
JsonObject tempS = sensors.createNestedObject ();
|
||||
tempS["i"] = g_lastSenUpdate.m_sensors[i].m_ind;
|
||||
tempS["v"] = int(g_lastSenUpdate.m_sensors[i].m_tempF);
|
||||
tempS["n"] = g_lastSenUpdate.m_sensors[i].m_name;
|
||||
}
|
||||
|
||||
char tempJson[2400];
|
||||
serializeJson(json, tempJson); // Export JSON object as a String
|
||||
request->send (200, "application/json", tempJson); // Send history data to the web client
|
||||
}
|
||||
|
||||
|
||||
// Send the history in JSON format.
|
||||
void SendHistory (AsyncWebServerRequest *request)
|
||||
{
|
||||
Serial.println ("Sending History");
|
||||
DynamicJsonDocument json(5560 + 100); // Current JSON static buffer
|
||||
JsonArray hist = json.createNestedArray ("hist");
|
||||
|
||||
for (SimpleList<DataPoint>::iterator it = g_tempHist.begin (); it != g_tempHist.end (); ++it)
|
||||
{
|
||||
JsonObject item = hist.createNestedObject ();
|
||||
item["t"] = it->m_time;
|
||||
JsonArray jsonSens = item.createNestedArray ("sensors");
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if (it->m_sensors[i].m_ind)
|
||||
{
|
||||
JsonObject sensor = jsonSens.createNestedObject ();
|
||||
sensor["n"] = it->m_sensors[i].m_name;
|
||||
sensor["v"] = int(it->m_sensors[i].m_tempF); // Lose the decimal places for space saving.
|
||||
}
|
||||
}
|
||||
}
|
||||
char tempJson[5560 + 100];
|
||||
serializeJson(json, tempJson); // Export JSON object as a String
|
||||
request->send (200, "application/json", tempJson); // Send history data to the web client
|
||||
}
|
||||
|
||||
// Add a data point to the history
|
||||
void AddDataPointToHistory ()
|
||||
{
|
||||
short validSensors = 0;
|
||||
bool validData = false;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if (g_lastSenUpdate.m_sensors[i].m_ind)
|
||||
{
|
||||
validSensors++;
|
||||
validData = true;
|
||||
}
|
||||
}
|
||||
// Clear the history if the count does not match.
|
||||
if (g_maxWorkingSensors != validSensors)
|
||||
{
|
||||
g_tempHist.clear ();
|
||||
g_maxWorkingSensors = validSensors;
|
||||
}
|
||||
|
||||
if (validData)
|
||||
{
|
||||
g_tempHist.push_back (g_lastSenUpdate);
|
||||
if (g_tempHist.size () > HIST_SIZE)
|
||||
{
|
||||
g_tempHist.erase (g_tempHist.begin ());
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
Serial.print ("size g_tempHist ");
|
||||
Serial.println (g_tempHist.size ());
|
||||
#endif
|
||||
}
|
||||
|
||||
void setup (void)
|
||||
{
|
||||
Serial.begin (115200);
|
||||
|
||||
// For battery voltage readings
|
||||
analogReadResolution (12);
|
||||
analogSetAttenuation (ADC_11db); // For all pins
|
||||
|
||||
// Temp probes
|
||||
g_ads.setGain (GAIN_ONE); // 1x gain +/- 4.096V 1 bit = 2mV 0.125mV
|
||||
g_ads.begin ();
|
||||
g_thermoCouples.begin ();
|
||||
g_thermoCouples.requestTemperatures ();
|
||||
g_thermoCouples.setResolution (12);
|
||||
|
||||
// WIFI connect
|
||||
ManageWifi ();
|
||||
|
||||
// OTA stuff
|
||||
setupOTA ("BBQ_Master");
|
||||
WiFi.setHostname("BBQ_Master");
|
||||
|
||||
// Web server stuff
|
||||
if (!SPIFFS.begin ())
|
||||
Serial.println ("SPIFFS Mount failed"); // Problème avec le stockage SPIFFS - Serious problem with SPIFFS
|
||||
g_server.on ("/measures.json", SendMeasures);
|
||||
g_server.on ("/history.json", SendHistory);
|
||||
|
||||
g_server.serveStatic ("/js/bootstrap.min.js", SPIFFS, "/js/bootstrap.min.js", "max-age=86400");
|
||||
g_server.serveStatic ("/js/jquery.min.js", SPIFFS, "/js/jquery-3.3.1.min.js", "max-age=86400");
|
||||
g_server.serveStatic ("/js/Chart.min.js", SPIFFS, "/js/Chart.min.js", "max-age=86400");
|
||||
g_server.serveStatic ("/js/moment.min.js", SPIFFS, "/js/moment.min.js", "max-age=86400");
|
||||
g_server.serveStatic ("/js/popper.min.js", SPIFFS, "/js/popper.min.js", "max-age=86400");
|
||||
g_server.serveStatic ("/css/custom.css", SPIFFS, "/css/custom.css");
|
||||
g_server.serveStatic ("/css/cover.css", SPIFFS, "/css/cover.css", "max-age=86400");
|
||||
g_server.serveStatic ("/css/bootstrap.min.css", SPIFFS, "/css/bootstrap.min.css", "max-age=86400");
|
||||
g_server.serveStatic ("/img/logo.png", SPIFFS, "/img/android-icon-72x72.png", "max-age=86400");
|
||||
g_server.serveStatic ("/favicon.ico", SPIFFS, "/img/favicon.ico", "max-age=86400");
|
||||
g_server.serveStatic ("/", SPIFFS, "/index.html");
|
||||
g_server.begin ();
|
||||
Serial.println ("HTTP server started");
|
||||
|
||||
// Real time
|
||||
NTP.onNTPSyncEvent ([](NTPSyncEvent_t error) {
|
||||
if (error)
|
||||
{
|
||||
Serial.print ("Time Sync error: ");
|
||||
if (error == noResponse)
|
||||
Serial.println ("NTP server not reachable");
|
||||
else if (error == invalidAddress)
|
||||
Serial.println ("Invalid NTP server address");
|
||||
g_ntpError = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print ("Got NTP time: ");
|
||||
Serial.println (NTP.getTimeDateString (NTP.getLastNTPSync ()));
|
||||
}
|
||||
});
|
||||
// NTP Server, time offset, daylight
|
||||
NTP.begin ("pool.ntp.org", -1, true);
|
||||
NTP.setInterval (60);
|
||||
}
|
||||
|
||||
void loop (void)
|
||||
{
|
||||
g_currentMillis = millis (); // Time now
|
||||
// Handle server requests
|
||||
ArduinoOTA.handle ();
|
||||
|
||||
// Add a point to the history over time.
|
||||
if (g_currentMillis - g_histPreviousMillis > HIST_INT)
|
||||
{
|
||||
g_histPreviousMillis = g_currentMillis;
|
||||
AddDataPointToHistory ();
|
||||
}
|
||||
|
||||
// If there is an error grabbing NTP time, try again.
|
||||
if (g_ntpError)
|
||||
{
|
||||
if (g_currentMillis - g_histPreviousMillis > NTP_RETRY_INT)
|
||||
{
|
||||
g_prevMilForNTPRetry = g_currentMillis;
|
||||
g_ntpError = false;
|
||||
NTP.getTime ();
|
||||
}
|
||||
}
|
||||
|
||||
// Read the sensor data.
|
||||
if (g_currentMillis - g_prevMilForInputRead >= SENSOR_READ_INT)
|
||||
{
|
||||
g_prevMilForInputRead = g_currentMillis;
|
||||
ReadSensors ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user