fixes, added about page

master
Ondřej Hruška 9 years ago
parent a778eb6d64
commit 46d861e0dc
  1. 6
      _web-build_do.sh
  2. 7
      esp_meas.pro
  3. 2
      esp_meas.pro.user
  4. 2
      html/css/app.css
  5. 5
      html/img/cvut.svg
  6. 5
      html/js/all.js
  7. 66
      html/pages/about.tpl
  8. 85
      html/pages/fft.html
  9. 6
      html/pages/status.tpl
  10. 12
      html/pages/wfm.html
  11. 4
      html/pages/wifi.tpl
  12. 6
      html_src/_start.php
  13. 2
      html_src/css/app.css
  14. 2
      html_src/css/app.css.map
  15. 1
      html_src/gulpfile.js
  16. 5
      html_src/img/cvut.svg
  17. 2
      html_src/js-src/lib/chartist.axis-title.js
  18. 71
      html_src/js-src/lib/chartist.js
  19. 25
      html_src/js-src/lib/chartist.zoom.js
  20. 3344
      html_src/js-src/lib/lodash.custom.js
  21. 190
      html_src/js-src/page_waveform.js
  22. 4
      html_src/js-src/page_wifi.js
  23. 32
      html_src/js-src/utils.js
  24. 5
      html_src/js/all.js
  25. 2
      html_src/js/all.js.map
  26. 44
      html_src/page_about.php
  27. 63
      html_src/page_fft.php
  28. 2
      html_src/page_status.php
  29. 11
      html_src/page_waveform.php
  30. 19
      html_src/sass/app.scss
  31. 2
      html_src/sass/form/_buttons.scss
  32. 2
      html_src/sass/layout/_box.scss
  33. 2
      html_src/sass/lib/chartist/_chartist-settings.scss
  34. 4
      html_src/sass/lib/chartist/_chartist.scss
  35. 17
      html_src/sass/pages/_about.scss
  36. 23
      html_src/sass/pages/_wfm.scss
  37. 0
      html_src/x_page_layout.php
  38. 2
      libesphttpd/include/httpd.h
  39. 2
      libesphttpd/include/logging.h
  40. 6
      user/fw_version.h
  41. 35
      user/page_about.c
  42. 8
      user/page_about.h
  43. 8
      user/routes.c
  44. 8
      user/user_main.c

@ -9,6 +9,7 @@ BLDDIR=html
rm -rf "$BLDDIR/pages"
rm -rf "$BLDDIR/js"
rm -rf "$BLDDIR/css"
rm -rf "$BLDDIR/img"
cd "$SRCDIR"
gulp --production
@ -16,11 +17,14 @@ cd ..
cp -R "$SRCDIR/css" "$BLDDIR"
cp -R "$SRCDIR/js" "$BLDDIR"
cp -R "$SRCDIR/img" "$BLDDIR"
find "$BLDDIR" -name "*.map" -delete
mkdir -p "$BLDDIR/pages"
php "$SRCDIR/page_status.php" > "$BLDDIR/pages/status.tpl"
php "$SRCDIR/page_about.php" > "$BLDDIR/pages/about.tpl"
php "$SRCDIR/page_wifi.php" > "$BLDDIR/pages/wifi.tpl"
php "$SRCDIR/page_waveform.php" > "$BLDDIR/pages/waveform.html" # no substitutions, .html allows to gzip it.
php "$SRCDIR/page_waveform.php" > "$BLDDIR/pages/wfm.html" # no substitutions, .html allows to gzip it.
php "$SRCDIR/page_fft.php" > "$BLDDIR/pages/fft.html" # same

@ -60,7 +60,8 @@ SOURCES += \
user/page_status.c \
user/page_waveform.c \
user/utils.c \
sbmp/library/payload_builder.c
sbmp/library/payload_builder.c \
user/page_about.c
HEADERS += \
include/uart_hw.h \
@ -142,7 +143,9 @@ HEADERS += \
user/page_waveform.h \
libesphttpd/include/espmissingprotos.h \
user/utils.h \
sbmp/library/payload_builder.h
sbmp/library/payload_builder.h \
user/page_about.h \
user/fw_version.h
DISTFILES += \
style.astylerc \

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 3.6.1, 2016-03-29T21:53:03. -->
<!-- Written by QtCreator 3.6.1, 2016-03-31T02:51:43. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.8 KiB

File diff suppressed because one or more lines are too long

@ -0,0 +1,66 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>About - Current analyzer</title>
<link href="/css/app.css" rel="stylesheet">
<script src="/js/all.js"></script>
</head>
<body class="page-about">
<div id="outer">
<nav id="menu">
<div id="brand" onclick="$('#menu').toggleClass('expanded')">Current Analyser</div>
<a href="/">Home</a><a href="/wifi">WiFi config</a><a href="/waveform">Waveform</a><a href="/fft">FFT</a><a href="/about" class="selected">About</a></nav>
<div id="content">
<h1>About</h1>
<div class="Box">
<img src="/img/cvut.svg" id="logo" class="mq-tablet-min">
<h2>Current Analyser</h2>
<img src="/img/cvut.svg" id="logo2" class="mq-phone">
<p>&copy; Ondřej Hruška, 2016 &lt;<a href="mailto:ondra@ondrovo.com" target="blank">ondra@ondrovo.com</a>&gt;</p>
<p><a href="http://measure.feld.cvut.cz/" target="blank">Katedra měření FEL ČVUT</a><br>Department of Measurement, FEE CTU</p>
</div>
<div class="Box">
<h2>Firmware</h2>
<p>
The ESP8266 firmware is based on the amazing <a href="https://github.com/Spritetm/esphttpd" target="blank">esp-httpd</a>
library by Jeroen Domburg.
</p>
<table>
<tr>
<th>Firmware</th>
<td>v%vers_fw%, build <i>%date%</i> at <i>%time%</i></td>
</tr>
<tr>
<th>HTTPD</th>
<td>v%vers_httpd%</td>
</tr>
<tr>
<th>SBMP</th>
<td>v%vers_sbmp%</td>
</tr>
<tr>
<th>IoT SDK</th>
<td>v%vers_sdk%</td>
</tr>
</table>
</div>
</div>
</div>
</body>
</html>

@ -0,0 +1,85 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>FFT - Current analyzer</title>
<link href="/css/app.css" rel="stylesheet">
<script src="/js/all.js"></script>
</head>
<body class="page-fft">
<div id="outer">
<nav id="menu">
<div id="brand" onclick="$('#menu').toggleClass('expanded')">Current Analyser</div>
<a href="/">Home</a><a href="/wifi">WiFi config</a><a href="/waveform">Waveform</a><a href="/fft" class="selected">FFT</a><a href="/about">About</a></nav>
<div id="content">
<h1>FFT</h1>
<div class="Box center" id="samp-ctrl">
<div>
<label for="count">Bins</label>
<label for="count" class="select-wrap">
<select name="count" id="count">
<!-- <option value="16">8-->
<!-- <option value="32">16-->
<!-- <option value="64">32-->
<!-- <option value="128">64-->
<!-- <option value="256">128-->
<option value="512">256
<option value="1024">512
<option value="2048" selected>1024
</select>
</label>
</div>
<div>
<label for="freq">Rate <span class="mq-tablet-max" style="font-weight:normal;">(Hz)</span></label>
<input id="freq" type="number" value="4096">
<span class="mq-normal-min">Hz</span>
</div>
<div>
<a id="load" class="button btn-green">Load</a>
</div>
</div>
<div class="Box medium chartbox">
<div id="chart" class="ct-chart ct-wide ct-with-area"></div>
<div class="stats invis">
<table>
<tr>
<th>Samples</th>
<td id="stat-count"></td>
</tr>
<tr>
<th>f<sub>s</sub></th>
<td id="stat-f-s"></td>
</tr>
<tr>
<th>I<sub>peak</sub></th>
<td id="stat-i-peak"></td>
</tr>
<tr>
<th>I<sub>RMS</sub></th>
<td id="stat-i-rms"></td>
</tr>
</table>
<div class="ar"><!-- auto reload -->
<input type="number" id="ar-time" step="0.5" value="1" min="0">&nbsp;s
<input type="button" id="ar-btn" class="btn-blue narrow" value="Auto">
</div>
</div>
</div>
<script>
$().ready(page_waveform.init('fft'));
</script>
</div>
</div>
</body>
</html>

@ -15,8 +15,8 @@
<body class="page-home">
<div id="outer">
<nav id="menu">
<div id="brand" onclick="$('#menu').toggleClass('expanded')">Current analyzer</div>
<a href="/" class="selected">Home</a><a href="/wifi">WiFi config</a><a href="/waveform">Waveform</a></nav>
<div id="brand" onclick="$('#menu').toggleClass('expanded')">Current Analyser</div>
<a href="/" class="selected">Home</a><a href="/wifi">WiFi config</a><a href="/waveform">Waveform</a><a href="/fft">FFT</a><a href="/about">About</a></nav>
<div id="content">
<h1>System Status</h1>
@ -24,7 +24,6 @@
<div class="Box">
<h2>Runtime</h2>
<table>
<tbody>
<tr>
<th>Uptime:</th>
<td id="uptime">%uptime%</td>
@ -33,7 +32,6 @@
<th>Free heap:</th>
<td id="heap">%heap%</td>
</tr>
</tbody>
</table>
</div>

@ -15,8 +15,8 @@
<body class="page-waveform">
<div id="outer">
<nav id="menu">
<div id="brand" onclick="$('#menu').toggleClass('expanded')">Current analyzer</div>
<a href="/">Home</a><a href="/wifi">WiFi config</a><a href="/waveform" class="selected">Waveform</a></nav>
<div id="brand" onclick="$('#menu').toggleClass('expanded')">Current Analyser</div>
<a href="/">Home</a><a href="/wifi">WiFi config</a><a href="/waveform" class="selected">Waveform</a><a href="/fft">FFT</a><a href="/about">About</a></nav>
<div id="content">
<h1>Waveform</h1>
@ -41,7 +41,7 @@
<div class="stats invis">
<table>
<tr>
<th>#</th>
<th>Samples</th>
<td id="stat-count"></td>
</tr>
<tr>
@ -57,11 +57,15 @@
<td id="stat-i-rms"></td>
</tr>
</table>
<div class="ar"><!-- auto reload -->
<input type="number" id="ar-time" step="0.5" value="1" min="0">&nbsp;s
<input type="button" id="ar-btn" class="btn-blue narrow" value="Auto">
</div>
</div>
</div>
<script>
$().ready(page_waveform.init());
$().ready(page_waveform.init('raw'));
</script>
</div>

@ -15,8 +15,8 @@
<body class="page-wifi">
<div id="outer">
<nav id="menu">
<div id="brand" onclick="$('#menu').toggleClass('expanded')">Current analyzer</div>
<a href="/">Home</a><a href="/wifi" class="selected">WiFi config</a><a href="/waveform">Waveform</a></nav>
<div id="brand" onclick="$('#menu').toggleClass('expanded')">Current Analyser</div>
<a href="/">Home</a><a href="/wifi" class="selected">WiFi config</a><a href="/waveform">Waveform</a><a href="/fft">FFT</a><a href="/about">About</a></nav>
<div id="content">
<h1>Wireless Setup</h1>

@ -4,10 +4,10 @@ $menu = [
'home' => [ '/', 'Home' ],
'wifi' => [ '/wifi', 'WiFi config' ],
'waveform' => [ '/waveform', 'Waveform' ],
// 'fft' => [ '/fft', 'FFT' ],
'fft' => [ '/fft', 'FFT' ],
// 'spectrogram' => [ '/spectrogram', 'Spectrogram' ],
// 'transient' => [ '/transient', 'Power-on transient' ],
// 'about' => [ '/about', 'Credits & About' ],
'about' => [ '/about', 'About' ],
];
$appname = 'Current analyzer';
@ -37,7 +37,7 @@ $appname = 'Current analyzer';
<body class="page-<?=$page?>">
<div id="outer">
<nav id="menu">
<div id="brand" onclick="$('#menu').toggleClass('expanded')">Current analyzer</div>
<div id="brand" onclick="$('#menu').toggleClass('expanded')">Current Analyser</div>
<?php
// generate the menu
foreach($menu as $k => $m) {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -24,6 +24,7 @@ elixir(function (mix) {
'js-src/lib/chartist.js',
'js-src/lib/chartist.axis-title.js',
'js-src/lib/chartist.zoom.js',
'js-src/lib/lodash.custom.js',
'js-src/utils.js',
'js-src/modal.js',
'js-src/app.js',

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.8 KiB

@ -42,8 +42,6 @@
options = Chartist.extend({}, defaultOptions, options);
console.log(options);
return function ctAxisTitle(chart) {
chart.on('created', function (data) {

@ -253,13 +253,13 @@ var Chartist = {
* @memberof Chartist.Core
* @type {Object}
*/
Chartist.escapingMap = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
'\'': '&#039;'
};
// Chartist.escapingMap = {
// '&': '&amp;',
// '<': '&lt;',
// '>': '&gt;',
// '"': '&quot;',
// '\'': '&#039;'
// };
/**
* This function serializes arbitrary data to a string. In case of data that can't be easily converted to a string, this function will create a wrapper object and serialize the data using JSON.stringify. The outcoming string will always be escaped using Chartist.escapingMap.
@ -278,9 +278,11 @@ var Chartist = {
data = JSON.stringify({data: data});
}
return Object.keys(Chartist.escapingMap).reduce(function(result, key) {
return Chartist.replaceAll(result, key, Chartist.escapingMap[key]);
}, data);
return _.escape(data);
// return Object.keys(Chartist.escapingMap).reduce(function(result, key) {
// return Chartist.replaceAll(result, key, Chartist.escapingMap[key]);
// }, data);
};
/**
@ -295,9 +297,10 @@ var Chartist = {
return data;
}
data = Object.keys(Chartist.escapingMap).reduce(function(result, key) {
return Chartist.replaceAll(result, Chartist.escapingMap[key], key);
}, data);
// data = Object.keys(Chartist.escapingMap).reduce(function(result, key) {
// return Chartist.replaceAll(result, Chartist.escapingMap[key], key);
// }, data);
data = _.unescape(data);
try {
data = JSON.parse(data);
@ -770,24 +773,24 @@ var Chartist = {
return bounds;
};
/**
* Calculate cartesian coordinates of polar coordinates
*
* @memberof Chartist.Core
* @param {Number} centerX X-axis coordinates of center point of circle segment
* @param {Number} centerY X-axis coordinates of center point of circle segment
* @param {Number} radius Radius of circle segment
* @param {Number} angleInDegrees Angle of circle segment in degrees
* @return {{x:Number, y:Number}} Coordinates of point on circumference
*/
Chartist.polarToCartesian = function (centerX, centerY, radius, angleInDegrees) {
var angleInRadians = (angleInDegrees - 90) * Math.PI / 180.0;
return {
x: centerX + (radius * Math.cos(angleInRadians)),
y: centerY + (radius * Math.sin(angleInRadians))
};
};
// /**
// * Calculate cartesian coordinates of polar coordinates
// *
// * @memberof Chartist.Core
// * @param {Number} centerX X-axis coordinates of center point of circle segment
// * @param {Number} centerY X-axis coordinates of center point of circle segment
// * @param {Number} radius Radius of circle segment
// * @param {Number} angleInDegrees Angle of circle segment in degrees
// * @return {{x:Number, y:Number}} Coordinates of point on circumference
// */
// Chartist.polarToCartesian = function (centerX, centerY, radius, angleInDegrees) {
// var angleInRadians = (angleInDegrees - 90) * Math.PI / 180.0;
//
// return {
// x: centerX + (radius * Math.cos(angleInRadians)),
// y: centerY + (radius * Math.sin(angleInRadians))
// };
// };
/**
* Initialize chart drawing rectangle (area where chart is drawn) x1,y1 = bottom left / x2,y2 = top right
@ -907,8 +910,10 @@ var Chartist = {
positionalData[axis.counterUnits.len] = axisOffset - 10;
var lblText = labels[index];
//round (!! will break for non-numeric)
lblText = Math.round(+lblText*100)/100;
if (_.isNumber(lblText)) {
lblText = Chartist.roundWithPrecision(lblText, 2);
}
if(useForeignObject) {
// We need to set width and height explicitly to px as span will not expand with width and height being

@ -189,8 +189,21 @@
var y2 = chartRect.y1 - rect.y;
var y1 = y2 - rect.height;
chart.options.axisX.highLow = { low: project(x1, axisX), high: project(x2, axisX) };
chart.options.axisY.highLow = { low: project(y1, axisY), high: project(y2, axisY) };
var xLow = project(x1, axisX);
var xHigh = project(x2, axisX);
var yLow = project(y1, axisY);
var yHigh = project(y2, axisY);
var explb = chart.options.explicitBounds;
if (!_.isUndefined(explb)) {
if (!_.isUndefined(explb.xLow)) xLow = Math.max(explb.xLow, xLow);
if (!_.isUndefined(explb.xHigh)) xHigh = Math.min(explb.xHigh, xHigh);
if (!_.isUndefined(explb.yLow)) yLow = Math.max(explb.yLow, yLow);
if (!_.isUndefined(explb.yHigh)) yHigh = Math.min(explb.yHigh, yHigh);
}
chart.options.axisX.highLow = {low: xLow, high: xHigh};
chart.options.axisY.highLow = {low: yLow, high: yHigh};
chart.update(chart.data, chart.options);
onZoom && onZoom(chart, reset);
@ -209,11 +222,11 @@
};
function hide(rect) {
rect.attr({ style: 'display:none' });
rect.attr({style: 'display:none'});
}
function show(rect) {
rect.attr({ style: 'display:block' });
rect.attr({style: 'display:block'});
}
function getRect(firstPoint, secondPoint) {
@ -248,7 +261,7 @@
point.x = x;
point.y = y;
point = point.matrixTransform(matrix.inverse());
return point || { x: 0, y: 0 };
return point || {x: 0, y: 0};
}
function project(value, axis) {
@ -266,7 +279,7 @@
return Math.log(val) / Math.log(base);
}
} (window, document, Chartist));
}(window, document, Chartist));
return Chartist.plugins.zoom;
}));

File diff suppressed because it is too large Load Diff

@ -2,31 +2,77 @@ var page_waveform = (function () {
var wfm = {};
var zoomResetFn;
var dataFormat;
function buildChart(obj, xlabel, ylabel) {
var points = [];
obj.samples.forEach(function (a, i) {
points.push({x: i, y: a});
});
var readoutPending = false;
var autoReload = false;
var autoReloadTime = 1;
var arTimeout = -1;
var zoomSavedX, zoomSavedY;
function buildChart(j) {
// Build the chart
var plugins = [];
var mql = window.matchMedia('screen and (min-width: 544px)');
var isPhone = !mql.matches;
if (!isPhone) {
// larger than phone
plugins.push(
var fft = (j.stats.format == 'FFT');
var xLabel, yLabel;
if (fft) {
xLabel = 'Frequency - [ Hz ]';
yLabel = 'Magnitude - [ mA ]';
} else {
xLabel = 'Sample time - [ ms ]';
yLabel = 'Current - [ mA ]';
}
var peak = Math.max(-j.stats.min, j.stats.max);
var displayPeak = Math.max(peak, 10);
// Sidebar
$('#stat-count').html(j.stats.count);
$('#stat-f-s').html(j.stats.freq);
$('#stat-i-peak').html(peak);
$('#stat-i-rms').html(j.stats.rms);
$('.stats').removeClass('invis');
// --- chart ---
// Generate point entries
// add synthetic properties
var step = fft ? (j.stats.freq/j.stats.count) : (1000/j.stats.freq);
var points = _.map(j.samples, function (a, i) {
return {
x: i * step,
y: a
};
});
var plugins = [
Chartist.plugins.zoom({
resetOnRightMouseBtn: true,
onZoom: function (chart, reset) {
zoomResetFn = reset;
zoomSavedX = chart.options.axisX.highLow;
zoomSavedY = chart.options.axisY.highLow;
}
})
];
if (!isPhone) plugins.push( // larger than phone
Chartist.plugins.ctAxisTitle({
axisX: {
axisTitle: xlabel,
axisTitle: xLabel,
offset: {
x: 0,
y: 55
}
},
axisY: {
axisTitle: ylabel,
axisTitle: yLabel,
flipText: true,
offset: {
x: 0,
@ -35,17 +81,19 @@ var page_waveform = (function () {
}
})
);
}
// zoom
plugins.push(Chartist.plugins.zoom({
resetOnRightMouseBtn:true,
onZoom: function(chart, reset) {
zoomResetFn = reset;
var xHigh, xLow, yHigh, yLow;
if (zoomSavedX) {
// we have saved coords of the zoom rect, restore the zoom.
xHigh = zoomSavedX.high;
xLow = zoomSavedX.low;
yHigh = zoomSavedY.high;
yLow = zoomSavedY.low;
} else {
yHigh = fft ? undefined : displayPeak;
yLow = fft ? 0 : -displayPeak;
}
}));
var peak = obj.stats.peak;
new Chartist.Line('#chart', {
series: [
@ -56,7 +104,7 @@ var page_waveform = (function () {
]
}, {
showPoint: false,
// showArea: true,
showArea: fft,
fullWidth: true,
chartPadding: (isPhone ? {right: 20, bottom: 5, left: 0} : {right: 25, bottom: 30, left: 25}),
series: {
@ -66,22 +114,32 @@ var page_waveform = (function () {
},
axisX: {
type: Chartist.AutoScaleAxis,
onlyInteger: true
//onlyInteger: !fft // only for raw
high: xHigh,
low: xLow,
},
axisY: {
type: Chartist.AutoScaleAxis,
//onlyInteger: true
high: peak,
low: -peak,
high: yHigh,
low: yLow,
},
explicitBounds: {
xLow: 0,
yLow: fft ? 0 : undefined,
xHigh: points[points.length-1].x
},
plugins: plugins
});
}
function onRxData(resp, status) {
readoutPending = false;
if (status != 200) {
// bad response
if (status != 0) { // 0 = aborted
alert("Request failed.");
}
return;
}
@ -91,46 +149,84 @@ var page_waveform = (function () {
return;
}
j.stats.peak = Math.max(-j.stats.min, j.stats.max);
if (autoReload)
arTimeout = setTimeout(requestReload, autoReloadTime);
buildChart(j, 'Sample number', 'Current - mA');
$('#stat-count').html(j.stats.count);
$('#stat-f-s').html(j.stats.freq);
$('#stat-i-peak').html(j.stats.peak);
$('#stat-i-rms').html(j.stats.rms);
$('.stats').removeClass('invis');
buildChart(j);
}
wfm.init = function() {
// var resp = {
// "samples": [1878, 1883, 1887, 1897, 1906, 1915, 1926, 1940, 1955, 1970, 1982, 1996, 2012, 2026, 2038, 2049],
// "success": true
// };
function requestReload() {
if (readoutPending) return false;
function loadBtnClick() {
var samples = $('#count').val();
var freq = $('#freq').val();
readoutPending = true;
//http://192.168.1.13
$().get('/api/raw.json?n='+samples+'&fs='+freq, onRxData, true, true);
var url = '/api/{fmt}.json?n={n}&fs={fs}'.format({
fmt: dataFormat,
n: $('#count').val(),
fs: $('#freq').val()
});
$().get(url, onRxData, true, true);
return true;
}
$('#load').on('click', loadBtnClick);
wfm.init = function (format) {
// --- Load data ---
dataFormat = format;
// initial
// requestReload();
$('#count,#freq').on('keyup', function(e) {
$('#load').on('click', requestReload);
$('#count,#freq').on('keyup', function (e) {
if (e.which == 13) {
loadBtnClick();
requestReload();
}
});
// chart zooming
$('#chart').on('contextmenu', function(e) {
// --- zooming ---
$('#chart').on('contextmenu', function (e) { // right click on the chart -> reset
zoomResetFn && zoomResetFn();
zoomResetFn = null;
zoomSavedX = null;
zoomSavedY = null;
e.preventDefault();
return false;
});
// --- scroll the input box ---
$('input[type=number]').on('mousewheel', function(e) {
var val = +$(this).val();
var step = +($(this).attr('step') || 1);
if(e.wheelDelta > 0) {
val += step;
} else {
val -= step;
}
$(this).val(val);
});
// auto-reload button
$('#ar-btn').on('click', function() {
autoReloadTime = +$('#ar-time').val() * 1000; // ms
autoReload = !autoReload;
if (autoReload) {
requestReload();
} else {
clearTimeout(arTimeout);
}
$('#ar-btn')
.toggleClass('btn-blue')
.toggleClass('btn-red')
.val(autoReload ? 'Stop' : 'Auto');
});
};
return wfm;

@ -50,7 +50,7 @@ var page_wifi = (function () {
var inner = document.createElement('div');
var $inner = $(inner).addClass('inner')
.htmlAppend('<div class="rssi">{0}</div>'.format(ap.rssi_perc))
.htmlAppend('<div class="essid" title="{0}">{0}</div>'.format(e(ap.essid)))
.htmlAppend('<div class="essid" title="{0}">{0}</div>'.format(_.escape(ap.essid)))
.htmlAppend('<div class="auth">{0}</div>'.format(authStr[ap.enc]));
$item.on('click', function () {
@ -76,7 +76,7 @@ var page_wifi = (function () {
/** Ask the CGI what APs are visible (async) */
function scanAPs() {
$().get('/wifi/scan.cgi', onScan, true, true); // no cache, no jsonp
$().get('http://192.168.1.13/wifi/scan.cgi', onScan, true, true); // no cache, no jsonp
}
function rescan(time) {

@ -2,32 +2,8 @@ function bool(x) {
return (x === 1 || x === '1' || x === true || x === 'true');
}
/** html entities */
function e(x) {
return String(x)
.replace(/&/g, '&amp;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;');
}
/** Returns true if argument is array [] */
function isArray(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
/** Returns true if argument is object {} */
function isObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]';
}
/** escape a string to have no special meaning in regex */
function regexEscape(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
/** Perform a substitution in the given string.
/**
* Perform a substitution in the given string.
*
* Arguments - array or list of replacements.
* Arguments numeric keys will replace {0}, {1} etc.
@ -42,7 +18,7 @@ String.prototype.format = function () {
var repl = arguments;
if (arguments.length == 1 && (isArray(arguments[0]) || isObject(arguments[0]))) {
if (arguments.length == 1 && (_.isArray(arguments[0]) || _.isObject(arguments[0]))) {
repl = arguments[0];
}
@ -55,7 +31,7 @@ String.prototype.format = function () {
}
// replace all occurrences
var pattern = new RegExp(regexEscape(ph), "g");
var pattern = new RegExp(_.escapeRegExp(ph), "g");
out = out.replace(pattern, repl[ph_orig]);
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,44 @@
<?php $page = 'about'; include "_start.php"; ?>
<h1>About</h1>
<div class="Box">
<img src="/img/cvut.svg" id="logo" class="mq-tablet-min">
<h2>Current Analyser</h2>
<img src="/img/cvut.svg" id="logo2" class="mq-phone">
<p>&copy; Ondřej Hruška, 2016 &lt;<a href="mailto:ondra@ondrovo.com" target="blank">ondra@ondrovo.com</a>&gt;</p>
<p><a href="http://measure.feld.cvut.cz/" target="blank">Katedra měření FEL ČVUT</a><br>Department of Measurement, FEE CTU</p>
</div>
<div class="Box">
<h2>Firmware</h2>
<p>
The ESP8266 firmware is based on the amazing <a href="https://github.com/Spritetm/esphttpd" target="blank">esp-httpd</a>
library by Jeroen Domburg.
</p>
<table>
<tr>
<th>Firmware</th>
<td>v%vers_fw%, build <i>%date%</i> at <i>%time%</i></td>
</tr>
<tr>
<th>HTTPD</th>
<td>v%vers_httpd%</td>
</tr>
<tr>
<th>SBMP</th>
<td>v%vers_sbmp%</td>
</tr>
<tr>
<th>IoT SDK</th>
<td>v%vers_sdk%</td>
</tr>
</table>
</div>
<?php include "_end.php"; ?>

@ -0,0 +1,63 @@
<?php $page = 'fft'; include "_start.php"; ?>
<h1>FFT</h1>
<div class="Box center" id="samp-ctrl">
<div>
<label for="count">Bins</label>
<label for="count" class="select-wrap">
<select name="count" id="count">
<!-- <option value="16">8-->
<!-- <option value="32">16-->
<!-- <option value="64">32-->
<!-- <option value="128">64-->
<!-- <option value="256">128-->
<option value="512">256
<option value="1024">512
<option value="2048" selected>1024
</select>
</label>
</div>
<div>
<label for="freq">Rate <span class="mq-tablet-max" style="font-weight:normal;">(Hz)</span></label>
<input id="freq" type="number" value="4096">
<span class="mq-normal-min">Hz</span>
</div>
<div>
<a id="load" class="button btn-green">Load</a>
</div>
</div>
<div class="Box medium chartbox">
<div id="chart" class="ct-chart ct-wide ct-with-area"></div>
<div class="stats invis">
<table>
<tr>
<th>Samples</th>
<td id="stat-count"></td>
</tr>
<tr>
<th>f<sub>s</sub></th>
<td id="stat-f-s"></td>
</tr>
<tr>
<th>I<sub>peak</sub></th>
<td id="stat-i-peak"></td>
</tr>
<tr>
<th>I<sub>RMS</sub></th>
<td id="stat-i-rms"></td>
</tr>
</table>
<div class="ar"><!-- auto reload -->
<input type="number" id="ar-time" step="0.5" value="1" min="0">&nbsp;s
<input type="button" id="ar-btn" class="btn-blue narrow" value="Auto">
</div>
</div>
</div>
<script>
$().ready(page_waveform.init('fft'));
</script>
<?php include "_end.php"; ?>

@ -6,7 +6,6 @@ include "_start.php"; ?>
<div class="Box">
<h2>Runtime</h2>
<table>
<tbody>
<tr>
<th>Uptime:</th>
<td id="uptime">%uptime%</td>
@ -15,7 +14,6 @@ include "_start.php"; ?>
<th>Free heap:</th>
<td id="heap">%heap%</td>
</tr>
</tbody>
</table>
</div>

@ -1,5 +1,4 @@
<?php $page = 'waveform';
include "_start.php"; ?>
<?php $page = 'waveform'; include "_start.php"; ?>
<h1>Waveform</h1>
@ -23,7 +22,7 @@ include "_start.php"; ?>
<div class="stats invis">
<table>
<tr>
<th>#</th>
<th>Samples</th>
<td id="stat-count"></td>
</tr>
<tr>
@ -39,11 +38,15 @@ include "_start.php"; ?>
<td id="stat-i-rms"></td>
</tr>
</table>
<div class="ar"><!-- auto reload -->
<input type="number" id="ar-time" step="0.5" value="1" min="0">&nbsp;s
<input type="button" id="ar-btn" class="btn-blue narrow" value="Auto">
</div>
</div>
</div>
<script>
$().ready(page_waveform.init());
$().ready(page_waveform.init('raw'));
</script>
<?php include "_end.php"; ?>

@ -45,29 +45,20 @@ $c-form-highlight-a: #28bc65;
@import "pages/wifi";
@import "pages/home";
@import "pages/wfm";
@import "pages/about";
/*
@include media($tablet-min) {
.mq-phone {
display: none;
}
.mq-phone { display: none; }
}
@include media($phone) {
.mq-tablet-min {
display: none;
}
.mq-tablet-min { display: none; }
}
*/
@include media($normal-min) {
.mq-tablet-max {
display: none;
}
.mq-tablet-max { display: none; }
}
@include media($tablet-max) {
.mq-normal-min {
display: none;
}
.mq-normal-min { display: none; }
}

@ -55,7 +55,7 @@ input[type="reset"], .btn-red {
@include fancy-btn-colors($btn-red-f, $btn-red-b, $btn-red-fa, $btn-red-ba)
}
//&.blue {@include fancy-btn-colors($btn-blue-f, $btn-blue-b, $btn-blue-fa, $btn-blue-ba)}
&.btn-blue {@include fancy-btn-colors($btn-blue-f, $btn-blue-b, $btn-blue-fa, $btn-blue-ba)}
//&, &.orange {@include fancy-btn-colors($btn-orange-f, $btn-orange-b, $btn-orange-fa, $btn-orange-ba)}
/*

@ -3,7 +3,7 @@
max-width: 900px;
margin-top: dist(0);
padding: dist(-1);
padding: dist(-1) dist(0);
@include media($phone) {
margin-top: dist(-1);

@ -30,7 +30,7 @@ $ct-point-size: 4px !default;
// Line chart point, can be either round or square
$ct-point-shape: round !default;
// Area fill transparency between 0 and 1
$ct-area-opacity: 0.1 !default;
$ct-area-opacity: 0.3 !default;
// Bar chart bar width
$ct-bar-width: 10px !default;

@ -207,6 +207,10 @@
@include ct-chart-line($ct-line-width);
}
.ct-with-area .ct-line {
stroke-width: 1px;
}
.ct-area {
@include ct-chart-area();
}

@ -0,0 +1,17 @@
.page-about {
.Box {
padding-left:dist(0);
padding-right:dist(0);
a {font-weight: bold;}
}
#logo {
float:right;
height: 130px;
}
#logo2 {
max-width: 150px;
}
}

@ -11,7 +11,7 @@
align-items: stretch;
> div {
margin: dist(-2);
margin: dist(-2) dist(-1);
}
label {
@ -19,8 +19,8 @@
font-weight: bold;
}
input {
width: 150px;
input,select {
width: 6em;
@include media($phone) {
width: 100%;
@ -38,6 +38,7 @@
.stats {
flex: 0 1;
position: relative;
@include media($phone) {
table {
@ -68,5 +69,21 @@
#stat-f-s:after {content: "Hz"}
#stat-i-peak:after {content: "mA"}
#stat-i-rms:after {content: "mA"}
// auto reload box
.ar {
position: absolute;
bottom:dist(-2);
width:100%;
text-align: center;
input[type=number] {
width: 4em;
}
input[type=button] {
margin-left: dist(-2);
}
}
}
}

@ -3,7 +3,7 @@
#include <esp8266.h>
#define HTTPDVER "0.4"
#define HTTPDVER "0.4-based"
#define HTTPD_CGI_MORE 0
#define HTTPD_CGI_DONE 1

@ -20,7 +20,7 @@
do { \
printf(LOG_EOL "\x1b[32;1m"); \
uptime_print(); \
printf(" [i] "fmt"\x1b[0m" LOG_EOL, ##__VA_ARGS__); \
printf(" [i] "fmt"\x1b[0m" LOG_EOL LOG_EOL, ##__VA_ARGS__); \
} while(0)

@ -0,0 +1,6 @@
#ifndef FW_VERSION_H
#define FW_VERSION_H
#define FIRMWARE_VERSION "0.1.1"
#endif // FW_VERSION_H

@ -0,0 +1,35 @@
#include <esp8266.h>
#include <httpd.h>
#include "page_about.h"
#include "fw_version.h"
#include "sbmp.h"
/** "About" page */
int FLASH_FN tplAbout(HttpdConnData *connData, char *token, void **arg)
{
// arg is unused
(void)arg;
if (token == NULL) return HTTPD_CGI_DONE;
if (streq(token, "vers_fw")) {
httpdSend(connData, FIRMWARE_VERSION, -1);
} else if (streq(token, "date")) {
httpdSend(connData, __DATE__, -1);
} else if (streq(token, "time")) {
httpdSend(connData, __TIME__, -1);
} else if (streq(token, "vers_httpd")) {
httpdSend(connData, HTTPDVER, -1);
} else if (streq(token, "vers_sbmp")) {
httpdSend(connData, SBMP_VER, -1);
} else if (streq(token, "vers_sdk")) {
httpdSend(connData, STR(ESP_SDK_VERSION), -1);
}
return HTTPD_CGI_DONE;
}

@ -0,0 +1,8 @@
#ifndef PAGE_ABOUT_H
#define PAGE_ABOUT_H
#include <httpd.h>
int tplAbout(HttpdConnData *connData, char *token, void **arg);
#endif // PAGE_ABOUT_H

@ -12,6 +12,7 @@
// user files
#include "page_status.h"
#include "page_waveform.h"
#include "page_about.h"
#define WIFI_PROTECT 0
@ -45,8 +46,13 @@ HttpdBuiltInUrl builtInUrls[] = {
ROUTE_TPL_FILE("/api/status.json", tplSystemStatus, "/json/status.tpl"),
// About
ROUTE_TPL_FILE("/about", tplAbout, "/pages/about.tpl"),
// Waveform page
ROUTE_FILE("/waveform", "/pages/waveform.html"), // static file, html -> can use gzip
ROUTE_FILE("/waveform", "/pages/wfm.html"), // static file, html -> can use gzip
// FFT
ROUTE_FILE("/fft", "/pages/fft.html"), // static file, html -> can use gzip
ROUTE_TPL_FILE("/api/raw.json", tplWaveformJSON, "/json/samples.tpl"),
ROUTE_TPL_FILE("/api/fft.json", tplFourierJSON, "/json/samples.tpl"),

@ -21,6 +21,7 @@
#include "datalink.h"
#include "uptime.h"
#include "routes.h"
#include "fw_version.h"
extern HttpdBuiltInUrl builtInUrls[];
@ -80,11 +81,14 @@ void user_init(void)
serialInit();
uptime_timer_init();
banner("*** ESP8266 starting ***");
banner("*** AC current analyser - WiFi module ***");
info("(c) Ondrej Hruska, 2016");
info("Katedra mereni FEL CVUT");
info("");
info("Version "FIRMWARE_VERSION", built "__DATE__" at "__TIME__);
info("HTTPD v."HTTPDVER", SBMP v."SBMP_VER", IoT SDK v."STR(ESP_SDK_VERSION));
printf(LOG_EOL);
// reset button etc
ioInit();

Loading…
Cancel
Save