Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "duinoapp-client",
"version": "3.1.2",
"version": "3.1.3",
"author": "Fraser Bullock",
"license": "GPL-3.0",
"private": true,
Expand Down
1 change: 1 addition & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>Duino App</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/canvasjs/1.7.0/canvasjs.min.js" integrity="sha512-FJ2OYvUIXUqCcPf1stu+oTBlhn54W0UisZB/TNrZaVMHHhYvLBV9jMbvJYtvDe5x/WVaoXZ6KB+Uqe5hT2vlyA==" crossorigin="anonymous"></script>
</head>
<body>
<noscript>
Expand Down
2 changes: 1 addition & 1 deletion service-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
workbox.core.setCacheNameDetails({ prefix: 'd4' });

// Do not touch this line
const LATEST_VERSION = '3.1.2';
const LATEST_VERSION = '3.1.3';

self.addEventListener('activate', (event) => {
console.log(`%c ${LATEST_VERSION} `, 'background: #ddd; color: #0000ff');
Expand Down
4 changes: 3 additions & 1 deletion src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
<serial-monitor height="calc(50vh - 96px)"/>
</v-tab-item>
<v-tab-item value="plotter">
graph coming soon
<serial-plotter height="calc(50vh - 96px)"/>
</v-tab-item>
</v-tabs-items>
</v-navigation-drawer>
Expand Down Expand Up @@ -103,6 +103,7 @@ import ServerFooter from './components/servers/footer-btn.vue';
import SerialFooter from './components/serial/footer-btn.vue';
import SerialPrompts from './components/serial/prompts.vue';
import SerialMonitor from './components/serial/monitor.vue';
import SerialPlotter from './components/serial/plotter.vue';
import CompileBtn from './components/program/compile.vue';
import UploadBtn from './components/program/upload.vue';
import CompileConsole from './components/program/console.vue';
Expand All @@ -116,6 +117,7 @@ export default {
SerialPrompts,
SerialFooter,
SerialMonitor,
SerialPlotter,
CompileBtn,
CompileConsole,
UploadBtn,
Expand Down
4 changes: 2 additions & 2 deletions src/components/serial/monitor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ export default {
this.$serial.on('clear', this.clearCB);
},
beforeDestroy() {
if (this.logCB) this.$serial.on('message', this.logCB);
if (this.clearCB) this.$serial.on('clear', this.clearCB);
if (this.logCB) this.$serial.off('message', this.logCB);
if (this.clearCB) this.$serial.off('clear', this.clearCB);
},
};
</script>
152 changes: 152 additions & 0 deletions src/components/serial/plotter.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
<template>
<div>
<div :id="id" :style="{ height }" />
<v-row class="px-4">
<v-col cols="2" class="py-0">
<v-select v-model="timeWindow" :items="windows" dense hide-details />
</v-col>
<v-col cols="2" class="py-0">
<rate />
</v-col>
<v-col cols="auto" class="py-0 mr-6">
<v-tooltip top>
<template #activator="{ on }">
<v-btn icon @click="clearCB && clearCB()" v-on="on">
<v-icon>mdi-cancel</v-icon>
</v-btn>
</template>
<span>Clear Monitor</span>
</v-tooltip>
<v-tooltip top>
<template #activator="{ on }">
<v-btn icon @click="paused = !paused" v-on="on">
<v-icon>mdi-{{ paused ? 'play' : 'pause'}}</v-icon>
</v-btn>
</template>
<span>{{ paused ? 'Play' : 'Pause'}} Monitor</span>
</v-tooltip>
<v-tooltip top>
<template #activator="{ on }">
<v-btn icon @click="chartOpts.axisY.includeZero = !chartOpts.axisY.includeZero" v-on="on">
<v-icon>mdi-{{ chartOpts.axisY.includeZero ? 'arrow-up-down' : 'arrow-vertical-lock'}}</v-icon>
</v-btn>
</template>
<span>{{ chartOpts.axisY.includeZero ? 'Auto Scale Y' : 'Lock Y to Zero'}}</span>
</v-tooltip>
</v-col>
</v-row>
</div>
</template>

<script>
/* eslint-disable no-param-reassign */
import Rate from './rate.vue';

export default {
components: {
Rate,
},
props: {
height: {
type: String,
default: '',
},
},
data() {
return {
data: null,
chart: null,
paused: false,
logCB: null,
clearCB: null,
lastRender: 0,
timeWindow: 60,
buff: '',
id: '',
dataOpts: {
xValueType: 'dateTime',
xValueFormatString: '',
},
chartOpts: {
axisY: {
includeZero: false,
},
},
windows: [
{ text: '1 Second', value: 1 },
{ text: '10 Seconds', value: 10 },
{ text: '30 Seconds', value: 30 },
{ text: '1 Minute', value: 60 },
{ text: '2 Minutes', value: 120 },
{ text: '5 Minutes', value: 300 },
{ text: '10 Minutes', value: 600 },
],
};
},
mounted() {
this.initChart();
this.logCB = (data) => {
const now = Date.now();
this.buff += data;
const parts = this.buff.split(/\r?\n/g);
if (parts.length < 2) return;
this.buff = /\r?\n$/.test(this.buff) ? '' : parts.pop();
parts.forEach((part) => {
const nums = part.split(/[\s,]+/g)
.map((num) => (num !== '' ? Number(num) : NaN))
.map((num) => (Number.isNaN(num) ? null : num));
if (!nums.some((num) => num !== null)) return;
if (nums.length > this.data.length) {
for (let i = 0; i < nums.length - this.data.length; i += 1) {
this.data.push({
type: 'line', dataPoints: [], pausedData: [], ...this.dataOpts,
});
}
}
this.data.forEach((datum, i) => {
if (typeof nums[i] === 'number') datum.pausedData.push({ x: now, y: nums[i] });
if (this.paused) {
datum.pausedData = datum.pausedData.filter((point) => now - point.x <= this.timeWindow * 1000);
return;
}
datum.dataPoints = [
...datum.dataPoints,
...datum.pausedData,
].filter((point) => now - point.x <= this.timeWindow * 1000);
datum.pausedData = [];
});
});
if (now - this.lastRender > 50 && this.chart) {
this.lastRender = now;
try {
this.chart.render();
} catch (err) {
// eslint-disable-next-line no-console
console.error(err);
}
}
};
this.$serial.on('message', this.logCB);
this.clearCB = () => {
this.initChart();
};
this.$serial.on('clear', this.clearCB);
},
methods: {
initChart() {
this.id = `chart-container-${Math.random()}`.replace('0.', '');
this.data = [];
this.$nextTick(() => {
this.chart = new window.CanvasJS.Chart(this.id, {
data: this.data,
...this.chartOpts,
});
});
},
},
beforeDestroy() {
if (this.logCB) this.$serial.off('message', this.logCB);
if (this.clearCB) this.$serial.off('clear', this.clearCB);
},
};
</script>
48 changes: 48 additions & 0 deletions src/components/settings/compiler.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<template>
<v-card outlined>
<v-card-title>
Code Compiler
</v-card-title>
<v-card-text>
<v-row>
<v-col cols="12" sm="6" md="4" class="py-0">
<v-checkbox
:input-value="!!settings.value.verbose"
label="Verbose Output"
hint="Show almost too much detail on what's happening"
persistent-hint
@change="$set(settings.value, 'verbose', $event)"
/>
</v-col>
</v-row>
</v-card-text>
</v-card>
</template>

<script>

export default {
computed: {
settings() {
const { Setting } = this.$FeathersVuex.api;
const { data } = Setting.findInStore({ query: { key: 'compiler' } });
if (data[0]) return data[0];
const settings = new Setting({ key: 'compiler' });
settings.save();
return settings;
},
},
methods: {
handleSave(to, from) {
if (JSON.stringify(to) === JSON.stringify(from)) return false;
this.settings.save();
return true;
},
},
watch: {
'settings.value.verbose': {
handler(to, from) { this.handleSave(to, from); },
},
},
};
</script>
38 changes: 32 additions & 6 deletions src/plugins/compile-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,14 @@ class CompileServer extends EventEmitter {
.reduce((a, i) => `${a}:${i}=${board.config[i]}`, board.fqbn);
}

// eslint-disable-next-line class-methods-use-this
_getFlags() {
const [settings] = store.getters['settings/find']({ query: { key: 'compiler' } }).data;
return {
verbose: settings?.value?.verbose || false,
};
}

// eslint-disable-next-line class-methods-use-this
_getUploadSpeed() {
const board = store.getters['boards/find']({ query: { uuid: store.getters.currentBoard } }).data[0];
Expand All @@ -241,7 +249,12 @@ class CompileServer extends EventEmitter {
const files = store.getters['files/find']({ query: { projectId: project.uuid } }).data
.map((f) => ({ content: f.body, name: `${project.ref}/${f.name}` }));
this.emit('console.progress', { percent: 0.25 * mod, message: 'Compiling code...' });
const res = await this.socket.emitAsync('compile.start', { fqbn: this._getFqbn(), files, noHex: !close });
const res = await this.socket.emitAsync('compile.start', {
fqbn: this._getFqbn(),
files,
noHex: !close,
flags: this._getFlags(),
});
if (res.error) {
this.emit('console.error', res.error);
throw new Error(res.error);
Expand All @@ -264,6 +277,8 @@ class CompileServer extends EventEmitter {
});
return;
}
const [board] = store.getters['boards/find']({ query: { uuid: store.getters.currentBoard } }).data;
const { protocol } = board?.props?.upload;
const speed = this._getUploadSpeed();
const speedDiff = this.Vue.$serial.baud !== speed;
// const hex = await this.compile(false);
Expand All @@ -286,12 +301,23 @@ class CompileServer extends EventEmitter {
const files = store.getters['files/find']({ query: { projectId: project.uuid } }).data
.map((f) => ({ content: f.body, name: `${project.ref}/${f.name}` }));

await this.Vue.$serial.setSignals('off');
await asyncTimeout(100);
await this.Vue.$serial.setSignals('on');
await asyncTimeout(200);
if (['arduino', 'wiring'].includes(protocol)) {
this.Vue.$serial._beforeWriteFn = async () => {
// eslint-disable-next-line no-console
// console.log('before write', protocol);
await this.Vue.$serial.setSignals('off');
await asyncTimeout(protocol === 'arduino' ? 250 : 50);
await this.Vue.$serial.setSignals('on');
await asyncTimeout(protocol === 'arduino' ? 250 : 100);
};
}

const err = await this.socket.emitAsync('upload.start', { id, fqbn: this._getFqbn(), files });
const err = await this.socket.emitAsync('upload.start', {
id,
fqbn: this._getFqbn(),
files,
flags: this._getFlags(),
});
await this.Vue.$serial.setSignals('off');

if (err) {
Expand Down
Loading