aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2026-08-07 18:45:15 +0000
committers-ol <s+removethis@s-ol.nu>2026-08-07 18:45:30 +0000
commit45eb6ff8ebfa5fabfa18457b1b48c5e4c5b7878f (patch)
tree6dfce936ff1248c36d786d874d20a339a902f39b
parentweb: reorganize sidebar (diff)
downloadt937-serial-45eb6ff8ebfa5fabfa18457b1b48c5e4c5b7878f.tar.gz
t937-serial-45eb6ff8ebfa5fabfa18457b1b48c5e4c5b7878f.zip
web: trace export button
-rw-r--r--web/index.html4
-rw-r--r--web/main.js25
2 files changed, 28 insertions, 1 deletions
diff --git a/web/index.html b/web/index.html
index 8ddfad4..34215ff 100644
--- a/web/index.html
+++ b/web/index.html
@@ -33,6 +33,10 @@
<label>controller</label>
<label id="temps_controller">-</label>
</div>
+ <div>
+ <label>export traces</label>
+ <button id="export" disabled>download csv</button>
+ </div>
<h2>manual controls</h2>
<div>
<label for="heat">heat</label>
diff --git a/web/main.js b/web/main.js
index 6d29a50..e568bbc 100644
--- a/web/main.js
+++ b/web/main.js
@@ -102,7 +102,7 @@ plot.addPlot('temp3', { color: 'sienna' });
plot.addPlot('tempavg', { color: 'rebeccapurple' });
const elements = [
- 'connect', 'status', 'temps_chamber', 'temps_controller',
+ 'connect', 'status', 'temps_chamber', 'temps_controller', 'export',
'profile', 'start', 'read', 'write',
'heat', 'heat_mode', 'cool', 'cool_mode',
'profile_load', 'profile_save', 'profile_delete', 'profile_show', 'profile_edit', 'profile_clear', 'profile_stored',
@@ -118,6 +118,7 @@ const updateUI = () => {
el.start.disabled = !ready;
el.read.disabled = !ready;
el.write.disabled = !ready;
+ el.export.disabled = !plot.PLOTS.tempavg.data.length;
el.profile_show.firstElementChild.firstElementChild.href.baseVal = plot.PLOTS.profile.visible ? '#i-eye' : '#i-no-eye';
el.paste_show.firstElementChild.firstElementChild.href.baseVal = plot.PLOTS.paste.visible ? '#i-eye' : '#i-no-eye';
@@ -278,6 +279,28 @@ for (const [slider, checkbox] of pwms) {
};
}
+el.export.onclick = () => {
+ const tavg = plot.PLOTS.tempavg.data;
+ const columns = [
+ plot.PLOTS.temp1.data,
+ plot.PLOTS.temp2.data,
+ plot.PLOTS.tempavg.data,
+ plot.PLOTS.temp3.data,
+ ];
+
+ let csv = 'Seconds,Chamber Temp 1,Chamber Temp 2,Chamber Average,Controller Temp\n';
+ for (let i = 0; i < tavg.length; i++) {
+ const data = columns.map(col => col[i][1]).join(',');
+ csv += `${tavg[i][0]},${data}\n`;
+ }
+
+ const a = document.createElement('a');
+ a.href = 'data:text/csv;charset=utf-8,' + encodeURI(csv);
+ a.target = '_blank';
+ a.download = `temps_${new Date().toISOString}.csv`;
+ a.click();
+};
+
el.start.onclick = () => {
if (STATUS === 'idle') {
STATUS = el.profile.value === '' ? 'manual' : 'running';