checkpoint
This commit is contained in:
11
package-lock.json
generated
11
package-lock.json
generated
@@ -15,7 +15,6 @@
|
||||
"jstransformer-scss": "^2.0.0",
|
||||
"jstransformer-stylus": "^1.5.0",
|
||||
"lodash.merge": "4.6.2",
|
||||
"lodash.omit": "^4.5.0",
|
||||
"pug-cli": "^1.0.0-alpha6"
|
||||
}
|
||||
},
|
||||
@@ -1915,11 +1914,6 @@
|
||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
|
||||
},
|
||||
"node_modules/lodash.omit": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz",
|
||||
"integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg=="
|
||||
},
|
||||
"node_modules/longest": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
|
||||
@@ -4614,11 +4608,6 @@
|
||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
|
||||
},
|
||||
"lodash.omit": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz",
|
||||
"integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg=="
|
||||
},
|
||||
"longest": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
"jstransformer-scss": "^2.0.0",
|
||||
"jstransformer-stylus": "^1.5.0",
|
||||
"lodash.merge": "4.6.2",
|
||||
"lodash.omit": "^4.5.0",
|
||||
"pug-cli": "^1.0.0-alpha6"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
const api = require("./api");
|
||||
const cookie = require("./cookie")("bbctrl-");
|
||||
const Sock = require("./sock");
|
||||
const omit = require("lodash.omit");
|
||||
|
||||
SvelteComponents.initNetworkInfo();
|
||||
SvelteComponents.createComponent("DialogHost",
|
||||
@@ -84,6 +83,7 @@ module.exports = new Vue({
|
||||
return {
|
||||
status: "connecting",
|
||||
currentView: "loading",
|
||||
display_units: localStorage.getItem("display_units") || "METRIC",
|
||||
index: -1,
|
||||
modified: false,
|
||||
template: require("../resources/config-template.json"),
|
||||
@@ -95,10 +95,6 @@ module.exports = new Vue({
|
||||
},
|
||||
state: {
|
||||
messages: [],
|
||||
probing_active: false,
|
||||
wait_for_probing_complete: false,
|
||||
show_probe_complete_modal: false,
|
||||
show_probe_failed_modal: false,
|
||||
},
|
||||
video_size: cookie.get("video-size", "small"),
|
||||
crosshair: cookie.get("crosshair", "false") != "false",
|
||||
@@ -130,11 +126,19 @@ module.exports = new Vue({
|
||||
"cheat-sheet-view": {
|
||||
template: "#cheat-sheet-view-template",
|
||||
data: function () {
|
||||
return { showUnimplemented: false };
|
||||
return {
|
||||
showUnimplemented: false
|
||||
};
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
display_units: function (value) {
|
||||
localStorage.setItem("display_units", value);
|
||||
},
|
||||
},
|
||||
|
||||
events: {
|
||||
"config-changed": function () {
|
||||
this.modified = true;
|
||||
@@ -142,7 +146,6 @@ module.exports = new Vue({
|
||||
|
||||
send: function (msg) {
|
||||
if (this.status == "connected") {
|
||||
console.debug(">", msg);
|
||||
this.sock.send(msg);
|
||||
}
|
||||
},
|
||||
@@ -214,10 +217,6 @@ module.exports = new Vue({
|
||||
},
|
||||
|
||||
methods: {
|
||||
metric: function () {
|
||||
return this.config.settings.units != "IMPERIAL";
|
||||
},
|
||||
|
||||
block_error_dialog: function () {
|
||||
this.errorTimeoutStart = Date.now();
|
||||
this.errorShow = false;
|
||||
@@ -297,6 +296,7 @@ module.exports = new Vue({
|
||||
if (typeof check == "undefined" || check) this.$emit("check");
|
||||
}
|
||||
|
||||
SvelteComponents.handleConfigUpdate(this.config);
|
||||
},
|
||||
|
||||
shutdown: function () {
|
||||
@@ -318,13 +318,9 @@ module.exports = new Vue({
|
||||
}
|
||||
|
||||
if ("log" in e.data) {
|
||||
if (e.data.log.msg === "Switch not found") {
|
||||
this.$broadcast("probing_failed");
|
||||
} else {
|
||||
if (e.data.log.msg !== "Switch not found") {
|
||||
this.$broadcast("log", e.data.log);
|
||||
}
|
||||
|
||||
delete e.data.log;
|
||||
}
|
||||
|
||||
// Check for session ID change on controller
|
||||
@@ -343,37 +339,11 @@ module.exports = new Vue({
|
||||
}
|
||||
}
|
||||
|
||||
// Set this to true to get console output of changes to the state
|
||||
const debugStateChanges = false;
|
||||
if (debugStateChanges) {
|
||||
const data = omit(e.data, [
|
||||
"vdd",
|
||||
"vin",
|
||||
"vout",
|
||||
"motor",
|
||||
"temp",
|
||||
"heartbeat",
|
||||
"load1",
|
||||
"load2",
|
||||
"rpi_temp",
|
||||
]);
|
||||
if (Object.keys(data).length > 0) {
|
||||
console.log(JSON.stringify(data, null, 4));
|
||||
}
|
||||
}
|
||||
|
||||
update_object(this.state, e.data, false);
|
||||
|
||||
if (this.state.pw === 0) {
|
||||
Vue.set(this.state, "saw_probe_connected", true);
|
||||
}
|
||||
SvelteComponents.handleControllerStateUpdate(this.state);
|
||||
|
||||
if (this.state.cycle === "idle") {
|
||||
if (this.state.wait_for_probing_complete) {
|
||||
Vue.set(this.state, "wait_for_probing_complete", false);
|
||||
this.$broadcast("probing_complete");
|
||||
}
|
||||
}
|
||||
delete this.state.log;
|
||||
|
||||
this.$broadcast("update");
|
||||
};
|
||||
@@ -406,7 +376,7 @@ module.exports = new Vue({
|
||||
this.currentView = parts[0];
|
||||
},
|
||||
|
||||
save: function () {
|
||||
save: async function () {
|
||||
const selected_tool = this.config.tool["selected-tool"];
|
||||
const saveModbus =
|
||||
selected_tool !== "pwm" &&
|
||||
@@ -423,16 +393,12 @@ module.exports = new Vue({
|
||||
|
||||
this.config["selected-tool-settings"][selected_tool] = settings;
|
||||
|
||||
api
|
||||
.put("config/save", this.config)
|
||||
.done(
|
||||
function (data) {
|
||||
this.modified = false;
|
||||
}.bind(this)
|
||||
)
|
||||
.fail(function (error) {
|
||||
api.alert("Save failed", error);
|
||||
});
|
||||
try {
|
||||
await api.put("config/save", this.config);
|
||||
this.modified = false;
|
||||
} catch (error) {
|
||||
api.alert("Save failed", error);
|
||||
}
|
||||
},
|
||||
|
||||
close_messages: function (action) {
|
||||
|
||||
@@ -4,6 +4,7 @@ module.exports = {
|
||||
props: ['state', 'config'],
|
||||
|
||||
computed: {
|
||||
metric: function () { this.$root.display_units === "METRIC" },
|
||||
x: function () { return this._compute_axis('x') },
|
||||
y: function () { return this._compute_axis('y') },
|
||||
z: function () { return this._compute_axis('z') },
|
||||
@@ -15,12 +16,14 @@ module.exports = {
|
||||
|
||||
methods: {
|
||||
_convert_length: function (value) {
|
||||
return this.state.imperial ? value / 25.4 : value;
|
||||
return this.metric
|
||||
? value
|
||||
: value / 25.4;
|
||||
},
|
||||
|
||||
_length_str: function (value) {
|
||||
return this._convert_length(value).toLocaleString() +
|
||||
(this.state.imperial ? ' in' : ' mm');
|
||||
(this.metric ? ' mm' : ' in');
|
||||
},
|
||||
|
||||
_compute_axis: function (axis) {
|
||||
|
||||
@@ -1,30 +1,3 @@
|
||||
/******************************************************************************\
|
||||
|
||||
This file is part of the Buildbotics firmware.
|
||||
|
||||
Copyright (c) 2015 - 2018, Buildbotics LLC
|
||||
All rights reserved.
|
||||
|
||||
This file ("the software") is free software: you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License,
|
||||
version 2 as published by the Free Software Foundation. You should
|
||||
have received a copy of the GNU General Public License, version 2
|
||||
along with the software. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
The software is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the software. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
For information regarding this software email:
|
||||
"Joseph Coffland" <joseph@buildbotics.com>
|
||||
|
||||
\******************************************************************************/
|
||||
|
||||
'use strict'
|
||||
|
||||
var api = require('./api');
|
||||
@@ -36,7 +9,7 @@ module.exports = {
|
||||
|
||||
data: function () {
|
||||
return {
|
||||
mach_units: 'METRIC',
|
||||
mach_units: this.$root.state.metric ? "METRIC" : "IMPERIAL",
|
||||
mdi: '',
|
||||
last_file: undefined,
|
||||
last_file_time: undefined,
|
||||
@@ -62,16 +35,26 @@ module.exports = {
|
||||
b: false,
|
||||
c: false
|
||||
},
|
||||
jog_incr_amounts: {
|
||||
"METRIC": {
|
||||
fine: 0.1,
|
||||
small: 1.0,
|
||||
medium: 10,
|
||||
large: 100,
|
||||
},
|
||||
"IMPERIAL": {
|
||||
fine: 0.005,
|
||||
small: 0.05,
|
||||
medium: 0.5,
|
||||
large: 5,
|
||||
}
|
||||
},
|
||||
axis_position: 0,
|
||||
jog_incr: localStorage.getItem("jog_incr") || 'small',
|
||||
jog_step: cookie.get_bool('jog-step'),
|
||||
jog_adjust: parseInt(cookie.get('jog-adjust', 2)),
|
||||
deleteGCode: false,
|
||||
tab: 'auto',
|
||||
jog_incr: 1.0,
|
||||
tool_diameter: 6.35,
|
||||
tool_diameter_for_prompt: 6.35,
|
||||
show_probe_test_modal: false,
|
||||
show_tool_diameter_modal: false,
|
||||
toolpath_msg: {
|
||||
x: false,
|
||||
y: false,
|
||||
@@ -93,33 +76,24 @@ module.exports = {
|
||||
'gcode-viewer': require('./gcode-viewer')
|
||||
},
|
||||
|
||||
|
||||
watch: {
|
||||
'state.imperial': {
|
||||
handler: function (imperial) {
|
||||
this.mach_units = imperial ? 'IMPERIAL' : 'METRIC';
|
||||
},
|
||||
immediate: true
|
||||
jog_incr: function (value) {
|
||||
localStorage.setItem("jog_incr", value);
|
||||
},
|
||||
|
||||
'state.bitDiameter': {
|
||||
handler: function (bitDiameter) {
|
||||
this.tool_diameter = bitDiameter;
|
||||
'state.metric': {
|
||||
handler: function (metric) {
|
||||
this.mach_units = metric
|
||||
? 'METRIC'
|
||||
: 'IMPERIAL';
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
|
||||
|
||||
mach_units: function (units) {
|
||||
if ((units == 'METRIC') != this.metric)
|
||||
this.send(units == 'METRIC' ? 'G21' : 'G20');
|
||||
|
||||
this.units_changed();
|
||||
},
|
||||
|
||||
'state.line': function () {
|
||||
if (this.mach_state != 'HOMING')
|
||||
if (this.mach_state != 'HOMING') {
|
||||
this.$broadcast('gcode-line', this.state.line);
|
||||
}
|
||||
},
|
||||
|
||||
'state.selected_time': function () {
|
||||
@@ -135,37 +109,56 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
computed: {
|
||||
metric: function () {
|
||||
return !this.state.imperial;
|
||||
display_units: {
|
||||
cache: false,
|
||||
get: function () {
|
||||
return this.$root.display_units;
|
||||
},
|
||||
set: function (value) {
|
||||
this.$root.display_units = value;
|
||||
}
|
||||
},
|
||||
|
||||
metric: function () {
|
||||
return this.display_units === "METRIC";
|
||||
},
|
||||
|
||||
mach_state: function () {
|
||||
var cycle = this.state.cycle;
|
||||
var state = this.state.xx;
|
||||
|
||||
if (typeof cycle != 'undefined' && state != 'ESTOPPED' &&
|
||||
(cycle == 'jogging' || cycle == 'homing'))
|
||||
(cycle == 'jogging' || cycle == 'homing')) {
|
||||
return cycle.toUpperCase();
|
||||
}
|
||||
|
||||
return state || ''
|
||||
},
|
||||
|
||||
|
||||
pause_reason: function () { return this.state.pr },
|
||||
|
||||
pause_reason: function () {
|
||||
return this.state.pr
|
||||
},
|
||||
|
||||
is_running: function () {
|
||||
return this.mach_state == 'RUNNING' || this.mach_state == 'HOMING';
|
||||
},
|
||||
|
||||
is_stopping: function () {
|
||||
return this.mach_state == 'STOPPING'
|
||||
},
|
||||
|
||||
is_stopping: function () { return this.mach_state == 'STOPPING' },
|
||||
is_holding: function () { return this.mach_state == 'HOLDING' },
|
||||
is_ready: function () { return this.mach_state == 'READY' },
|
||||
is_idle: function () { return this.state.cycle == 'idle' },
|
||||
is_holding: function () {
|
||||
return this.mach_state == 'HOLDING'
|
||||
},
|
||||
|
||||
is_ready: function () {
|
||||
return this.mach_state == 'READY'
|
||||
},
|
||||
|
||||
is_idle: function () {
|
||||
return this.state.cycle == 'idle'
|
||||
},
|
||||
|
||||
is_paused: function () {
|
||||
return this.is_holding &&
|
||||
@@ -173,9 +166,9 @@ module.exports = {
|
||||
this.pause_reason == 'Program pause')
|
||||
},
|
||||
|
||||
|
||||
can_mdi: function () { return this.is_idle || this.state.cycle == 'mdi' },
|
||||
|
||||
can_mdi: function () {
|
||||
return this.is_idle || this.state.cycle == 'mdi'
|
||||
},
|
||||
|
||||
can_set_axis: function () {
|
||||
return this.is_idle
|
||||
@@ -183,47 +176,59 @@ module.exports = {
|
||||
return this.is_idle || this.is_paused
|
||||
},
|
||||
|
||||
|
||||
message: function () {
|
||||
if (this.mach_state == 'ESTOPPED') return this.state.er;
|
||||
if (this.mach_state == 'HOLDING') return this.state.pr;
|
||||
if (this.state.messages.length)
|
||||
if (this.mach_state == 'ESTOPPED') {
|
||||
return this.state.er;
|
||||
}
|
||||
|
||||
if (this.mach_state == 'HOLDING') {
|
||||
return this.state.pr;
|
||||
}
|
||||
|
||||
if (this.state.messages.length) {
|
||||
return this.state.messages.slice(-1)[0].text;
|
||||
}
|
||||
|
||||
return '';
|
||||
},
|
||||
|
||||
|
||||
highlight_state: function () {
|
||||
return this.mach_state == 'ESTOPPED' || this.mach_state == 'HOLDING';
|
||||
},
|
||||
|
||||
|
||||
plan_time: function () { return this.state.plan_time },
|
||||
|
||||
plan_time: function () {
|
||||
return this.state.plan_time
|
||||
},
|
||||
|
||||
plan_time_remaining: function () {
|
||||
if (!(this.is_stopping || this.is_running || this.is_holding)) return 0;
|
||||
if (!(this.is_stopping || this.is_running || this.is_holding)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return this.toolpath.time - this.plan_time
|
||||
},
|
||||
|
||||
|
||||
eta: function () {
|
||||
if (this.mach_state != 'RUNNING') return '';
|
||||
if (this.mach_state != 'RUNNING') {
|
||||
return '';
|
||||
}
|
||||
|
||||
var remaining = this.plan_time_remaining;
|
||||
var d = new Date();
|
||||
d.setSeconds(d.getSeconds() + remaining);
|
||||
return d.toLocaleString();
|
||||
},
|
||||
|
||||
|
||||
progress: function () {
|
||||
if (!this.toolpath.time || this.is_ready) return 0;
|
||||
if (!this.toolpath.time || this.is_ready) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var p = this.plan_time / this.toolpath.time;
|
||||
return p < 1 ? p : 1;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
events: {
|
||||
jog: function (axis, power) {
|
||||
var data = { ts: new Date().getTime() };
|
||||
@@ -232,244 +237,34 @@ module.exports = {
|
||||
},
|
||||
|
||||
back2zero: function (axis0, axis1) {
|
||||
this.send("G0" + axis0 + "0" + axis1 + "0");
|
||||
this.send(`G0 ${axis0}0 ${axis1}0`);
|
||||
},
|
||||
|
||||
step: function (axis, value) {
|
||||
this.send('M70\nG91\nG0' + axis + value + '\nM72');
|
||||
this.send(`
|
||||
M70
|
||||
G91
|
||||
G0 ${axis}${value}
|
||||
M72
|
||||
`);
|
||||
},
|
||||
|
||||
probing_failed: function () {
|
||||
Vue.set(this.state, "probing_active", false);
|
||||
Vue.set(this.state, "wait_for_probing_complete", false);
|
||||
Vue.set(this.state, "show_probe_complete_modal", false);
|
||||
Vue.set(this.state, "goto_xy_zero_after_probe", false);
|
||||
|
||||
Vue.set(this.state, "show_probe_failed_modal", true);
|
||||
},
|
||||
|
||||
probing_complete: function () {
|
||||
Vue.set(this.state, "probing_active", false);
|
||||
|
||||
if (this.config.settings['probing-prompts']) {
|
||||
Vue.set(this.state, "show_probe_complete_modal", true);
|
||||
} else {
|
||||
this.$emit("finalize_probe");
|
||||
}
|
||||
},
|
||||
|
||||
finalize_probe: function () {
|
||||
Vue.set(this.state, "show_probe_complete_modal", false);
|
||||
|
||||
if (this.state.goto_xy_zero_after_probe) {
|
||||
this.goto_zero(1, 1, 0, 0);
|
||||
}
|
||||
|
||||
Vue.set(this.state, "goto_xy_zero_after_probe", false);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
ready: function () {
|
||||
this.load()
|
||||
this.load();
|
||||
|
||||
SvelteComponents.registerControllerMethods({
|
||||
send: (...args) => this.send(...args),
|
||||
goto_zero: (...args) => this.goto_zero(...args)
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
methods: {
|
||||
units_changed: function () {
|
||||
if (this.mach_units == 'METRIC') {
|
||||
document.getElementById("jog_button_fine").innerHTML = "0.1";
|
||||
document.getElementById("jog_button_small").innerHTML = "1.0";
|
||||
document.getElementById("jog_button_medium").innerHTML = "10";
|
||||
document.getElementById("jog_button_large").innerHTML = "100";
|
||||
} else {
|
||||
document.getElementById("jog_button_fine").innerHTML = "0.005";
|
||||
document.getElementById("jog_button_small").innerHTML = "0.05";
|
||||
document.getElementById("jog_button_medium").innerHTML = "0.5";
|
||||
document.getElementById("jog_button_large").innerHTML = "5";
|
||||
}
|
||||
|
||||
this.set_jog_incr('small');
|
||||
},
|
||||
|
||||
start_probe_test: function (on_finish) {
|
||||
if (!this.config.settings['probing-prompts']) {
|
||||
on_finish();
|
||||
return;
|
||||
}
|
||||
|
||||
this.show_probe_test_modal = true;
|
||||
Vue.set(this.state, "saw_probe_connected", false);
|
||||
Vue.set(this.state, "on_probe_finish", on_finish);
|
||||
},
|
||||
|
||||
finish_probe_test: function () {
|
||||
this.show_probe_test_modal = false;
|
||||
Vue.set(this.state, "saw_probe_connected", false);
|
||||
|
||||
const on_finish = this.state.on_probe_finish;
|
||||
Vue.set(this.state, "on_probe_finish", undefined);
|
||||
|
||||
on_finish();
|
||||
},
|
||||
|
||||
hide_probe_failed_modal: function () {
|
||||
Vue.set(this.state, "show_probe_failed_modal", false);
|
||||
},
|
||||
|
||||
prep_and_show_tool_diameter_modal() {
|
||||
this.tool_diameter_for_prompt = (this.mach_units == 'METRIC')
|
||||
? this.tool_diameter
|
||||
: this.tool_diameter / 25.4;
|
||||
|
||||
this.tool_diameter_for_prompt = this.tool_diameter_for_prompt.toFixed(3).replace(/0+$/, "");
|
||||
|
||||
this.show_tool_diameter_modal = true;
|
||||
},
|
||||
|
||||
set_tool_diameter() {
|
||||
this.tool_diameter = parseFloat(this.tool_diameter_for_prompt);
|
||||
|
||||
if (!isFinite(this.tool_diameter)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.show_tool_diameter_modal = false;
|
||||
|
||||
if (this.mach_units !== "METRIC") {
|
||||
this.tool_diameter *= 25.4;
|
||||
}
|
||||
|
||||
this.probe_xyz();
|
||||
},
|
||||
|
||||
probe(zOnly = false) {
|
||||
const xdim = this.config.probe["probe-xdim"];
|
||||
const ydim = this.config.probe["probe-ydim"];
|
||||
const zdim = this.config.probe["probe-zdim"];
|
||||
const slowSeek = this.config.probe["probe-slow-seek"];
|
||||
const fastSeek = this.config.probe["probe-fast-seek"];
|
||||
|
||||
const zlift = 1;
|
||||
const xoffset = xdim + (this.tool_diameter / 2.0);
|
||||
const yoffset = ydim + (this.tool_diameter / 2.0);
|
||||
const zoffset = zdim;
|
||||
|
||||
const metric = this.mach_units == "METRIC";
|
||||
const mm = n => (metric ? n : n / 25.4).toFixed(5);
|
||||
const speed = s => `F${mm(s)}`;
|
||||
|
||||
// After probing Z, we want to drop the bit down:
|
||||
// Ideally, 12.7mm/0.5in
|
||||
// And we don't want to be more than 75% down on the probe block
|
||||
// Also, add zlift to compensate for the fact that we lift after probing Z
|
||||
const plunge = Math.min(12.7, zoffset * 0.75) + zlift;
|
||||
|
||||
Vue.set(this.state, "probing_active", true);
|
||||
Vue.set(this.state, "goto_xy_zero_after_probe", !zOnly);
|
||||
|
||||
if (zOnly) {
|
||||
this.send(`
|
||||
${metric ? "G21" : "G20"}
|
||||
G92 Z0
|
||||
|
||||
G38.2 Z ${mm(-25.4)} ${speed(fastSeek)}
|
||||
G91 G1 Z ${mm(1)}
|
||||
G38.2 Z ${mm(-2)} ${speed(slowSeek)}
|
||||
G92 Z ${mm(zoffset)}
|
||||
|
||||
G91 G0 Z ${mm(3)}
|
||||
|
||||
M2
|
||||
`);
|
||||
} else {
|
||||
this.send(`
|
||||
${metric ? "G21" : "G20"}
|
||||
G92 X0 Y0 Z0
|
||||
|
||||
G38.2 Z ${mm(-25.4)} ${speed(fastSeek)}
|
||||
G91 G1 Z ${mm(1)}
|
||||
G38.2 Z ${mm(-2)} ${speed(slowSeek)}
|
||||
G92 Z ${mm(zoffset)}
|
||||
|
||||
G91 G0 Z ${mm(zlift)}
|
||||
G91 G0 X ${mm(20)}
|
||||
G91 G0 Z ${mm(-plunge)}
|
||||
G38.2 X ${mm(-20)} ${speed(fastSeek)}
|
||||
G91 G1 X ${mm(1)}
|
||||
G38.2 X ${mm(-2)} ${speed(slowSeek)}
|
||||
G92 X ${mm(xoffset)}
|
||||
|
||||
G91 G0 X ${mm(1)}
|
||||
G91 G0 Y ${mm(20)}
|
||||
G91 G0 X ${mm(-20)}
|
||||
G38.2 Y ${mm(-20)} ${speed(fastSeek)}
|
||||
G91 G1 Y ${mm(1)}
|
||||
G38.2 Y ${mm(-2)} ${speed(slowSeek)}
|
||||
G92 Y ${mm(yoffset)}
|
||||
|
||||
G91 G0 Y ${mm(3)}
|
||||
G91 G0 Z ${mm(25.4)}
|
||||
|
||||
M2
|
||||
`);
|
||||
}
|
||||
|
||||
// Wait 1 second to let the probing sequence begin,
|
||||
// then wait for probing to be complete
|
||||
setTimeout(() => Vue.set(this.state, "wait_for_probing_complete", true), 1000);
|
||||
},
|
||||
|
||||
probe_xyz() {
|
||||
this.probe(false);
|
||||
},
|
||||
|
||||
probe_z() {
|
||||
this.probe(true);
|
||||
},
|
||||
|
||||
set_jog_incr: function (newValue) {
|
||||
document.getElementById("jog_button_fine").style.fontWeight = 'normal';
|
||||
document.getElementById("jog_button_small").style.fontWeight = 'normal';
|
||||
document.getElementById("jog_button_medium").style.fontWeight = 'normal';
|
||||
document.getElementById("jog_button_large").style.fontWeight = 'normal';
|
||||
|
||||
if (newValue == 'fine') {
|
||||
document.getElementById("jog_button_fine").style.fontWeight = 'bold';
|
||||
if (this.mach_units == 'METRIC')
|
||||
this.jog_incr = 0.1;
|
||||
else
|
||||
this.jog_incr = 0.005;
|
||||
} else if (newValue == 'small') {
|
||||
document.getElementById("jog_button_small").style.fontWeight = 'bold';
|
||||
if (this.mach_units == 'METRIC')
|
||||
this.jog_incr = 1.0;
|
||||
else
|
||||
this.jog_incr = 0.05;
|
||||
} else if (newValue == 'medium') {
|
||||
document.getElementById("jog_button_medium").style.fontWeight = 'bold';
|
||||
if (this.mach_units == 'METRIC')
|
||||
this.jog_incr = 10;
|
||||
else
|
||||
this.jog_incr = 0.5;
|
||||
} else if (newValue == 'large') {
|
||||
document.getElementById("jog_button_large").style.fontWeight = 'bold';
|
||||
|
||||
this.jog_incr = (this.mach_units == 'METRIC')
|
||||
? 100
|
||||
: 5;
|
||||
}
|
||||
},
|
||||
|
||||
goto_zero(zero_x, zero_y, zero_z, zero_a) {
|
||||
var xcmd = "";
|
||||
var ycmd = "";
|
||||
var zcmd = "";
|
||||
var acmd = "";
|
||||
if (zero_x) xcmd = "X0";
|
||||
if (zero_y) ycmd = "Y0";
|
||||
if (zero_z) zcmd = "Z0";
|
||||
if (zero_a) acmd = "A0";
|
||||
const xcmd = zero_x ? "X0" : "";
|
||||
const ycmd = zero_y ? "Y0" : "";
|
||||
const zcmd = zero_z ? "Z0" : "";
|
||||
const acmd = zero_a ? "A0" : "";
|
||||
|
||||
this.ask_zero_xy_msg = false;
|
||||
this.ask_zero_z_msg = false;
|
||||
@@ -477,13 +272,25 @@ module.exports = {
|
||||
this.send('G90\nG0' + xcmd + ycmd + zcmd + acmd + '\n');
|
||||
},
|
||||
|
||||
jog_fn: function (x_jog, y_jog, z_jog, a_jog) {
|
||||
var xcmd = "X" + x_jog * this.jog_incr;
|
||||
var ycmd = "Y" + y_jog * this.jog_incr;
|
||||
var zcmd = "Z" + z_jog * this.jog_incr;
|
||||
var acmd = "A" + a_jog * this.jog_incr;
|
||||
getJogIncrFontWeight(value) {
|
||||
const weight = this.jog_incr === value ? 'bold' : 'normal';
|
||||
|
||||
this.send('G91\nG0' + xcmd + ycmd + zcmd + acmd + '\n');
|
||||
return `font-weight:${weight}`;
|
||||
},
|
||||
|
||||
jog_fn: function (x_jog, y_jog, z_jog, a_jog) {
|
||||
const amount = this.jog_incr_amounts[this.display_units][this.jog_incr];
|
||||
|
||||
var xcmd = "X" + x_jog * amount;
|
||||
var ycmd = "Y" + y_jog * amount;
|
||||
var zcmd = "Z" + z_jog * amount;
|
||||
var acmd = "A" + a_jog * amount;
|
||||
|
||||
this.send(`
|
||||
G91
|
||||
${this.metric ? "G21" : "G20"}
|
||||
G0 ${xcmd}${ycmd}${zcmd}${acmd}
|
||||
`);
|
||||
},
|
||||
|
||||
send: function (msg) {
|
||||
@@ -493,7 +300,10 @@ module.exports = {
|
||||
load: function () {
|
||||
var file_time = this.state.selected_time;
|
||||
var file = this.state.selected;
|
||||
if (this.last_file == file && this.last_file_time == file_time) return;
|
||||
if (this.last_file == file && this.last_file_time == file_time) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.last_file = file;
|
||||
this.last_file_time = file_time;
|
||||
|
||||
@@ -503,12 +313,12 @@ module.exports = {
|
||||
this.load_toolpath(file, file_time);
|
||||
},
|
||||
|
||||
|
||||
load_toolpath: async function (file, file_time) {
|
||||
this.toolpath = {};
|
||||
|
||||
if (!file) return;
|
||||
if (this.last_file_time != file_time) return;
|
||||
if (!file || this.last_file_time != file_time) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.showGcodeMessage = true;
|
||||
|
||||
@@ -534,30 +344,30 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
submit_mdi: function () {
|
||||
this.send(this.mdi);
|
||||
if (!this.history.length || this.history[0] != this.mdi)
|
||||
|
||||
if (!this.history.length || this.history[0] != this.mdi) {
|
||||
this.history.unshift(this.mdi);
|
||||
}
|
||||
|
||||
this.mdi = '';
|
||||
},
|
||||
|
||||
|
||||
mdi_start_pause: function () {
|
||||
if (this.state.xx == 'RUNNING') this.pause();
|
||||
|
||||
else if (this.state.xx == 'STOPPING' || this.state.xx == 'HOLDING')
|
||||
if (this.state.xx == 'RUNNING') {
|
||||
this.pause();
|
||||
} else if (this.state.xx == 'STOPPING' || this.state.xx == 'HOLDING') {
|
||||
this.unpause();
|
||||
|
||||
else this.submit_mdi();
|
||||
} else {
|
||||
this.submit_mdi();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
load_history: function (index) {
|
||||
this.mdi = this.history[index];
|
||||
},
|
||||
|
||||
|
||||
open: function (e) {
|
||||
// If we don't reset the form the browser may cache file if name is same
|
||||
// even if contents have changed
|
||||
@@ -565,7 +375,6 @@ module.exports = {
|
||||
$('.gcode-file-input input').click();
|
||||
},
|
||||
|
||||
|
||||
upload: async function (e) {
|
||||
const files = e.target.files || e.dataTransfer.files;
|
||||
if (!files.length) {
|
||||
@@ -601,7 +410,6 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
delete_current: function () {
|
||||
if (this.state.selected) {
|
||||
api.delete('file/' + this.state.selected);
|
||||
@@ -610,41 +418,33 @@ module.exports = {
|
||||
this.deleteGCode = false;
|
||||
},
|
||||
|
||||
|
||||
delete_all: function () {
|
||||
api.delete('file');
|
||||
this.deleteGCode = false;
|
||||
},
|
||||
|
||||
|
||||
home: function (axis) {
|
||||
this.ask_home = false;
|
||||
|
||||
if (typeof axis == 'undefined') {
|
||||
api.put('home');
|
||||
} else if (this[axis].homingMode != 'manual') {
|
||||
api.put('home/' + axis);
|
||||
} else {
|
||||
if (this[axis].homingMode != 'manual') {
|
||||
api.put('home/' + axis);
|
||||
}
|
||||
else {
|
||||
this.manual_home[axis] = true;
|
||||
}
|
||||
this.manual_home[axis] = true;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
set_home: function (axis, position) {
|
||||
this.manual_home[axis] = false;
|
||||
api.put('home/' + axis + '/set', { position: parseFloat(position) });
|
||||
},
|
||||
|
||||
|
||||
unhome: function (axis) {
|
||||
this.position_msg[axis] = false;
|
||||
api.put('home/' + axis + '/clear');
|
||||
},
|
||||
|
||||
|
||||
show_set_position: function (axis) {
|
||||
this.axis_position = 0;
|
||||
this.position_msg[axis] = true;
|
||||
@@ -654,61 +454,84 @@ module.exports = {
|
||||
this.toolpath_msg[axis] = true;
|
||||
},
|
||||
|
||||
|
||||
set_position: function (axis, position) {
|
||||
this.position_msg[axis] = false;
|
||||
api.put('position/' + axis, { 'position': parseFloat(position) });
|
||||
},
|
||||
|
||||
|
||||
zero_all: function () {
|
||||
for (var axis of 'xyzabc')
|
||||
if (this[axis].enabled) this.zero(axis);
|
||||
for (var axis of 'xyzabc') {
|
||||
if (this[axis].enabled) {
|
||||
this.zero(axis);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
zero: function (axis) {
|
||||
if (typeof axis == 'undefined') this.zero_all();
|
||||
else this.set_position(axis, 0);
|
||||
if (typeof axis == 'undefined') {
|
||||
this.zero_all();
|
||||
} else {
|
||||
this.set_position(axis, 0);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
start_pause: function () {
|
||||
if (this.state.xx == 'RUNNING') this.pause();
|
||||
|
||||
else if (this.state.xx == 'STOPPING' || this.state.xx == 'HOLDING')
|
||||
if (this.state.xx == 'RUNNING') {
|
||||
this.pause();
|
||||
} else if (this.state.xx == 'STOPPING' || this.state.xx == 'HOLDING') {
|
||||
this.unpause();
|
||||
|
||||
else this.start();
|
||||
} else {
|
||||
this.start();
|
||||
}
|
||||
},
|
||||
|
||||
start: function () {
|
||||
api.put('start')
|
||||
},
|
||||
|
||||
start: function () { api.put('start') },
|
||||
pause: function () { api.put('pause') },
|
||||
unpause: function () { api.put('unpause') },
|
||||
optional_pause: function () { api.put('pause/optional') },
|
||||
stop: function () { api.put('stop') },
|
||||
step: function () { api.put('step') },
|
||||
pause: function () {
|
||||
api.put('pause')
|
||||
},
|
||||
|
||||
unpause: function () {
|
||||
api.put('unpause')
|
||||
},
|
||||
|
||||
override_feed: function () { api.put('override/feed/' + this.feed_override) },
|
||||
optional_pause: function () {
|
||||
api.put('pause/optional')
|
||||
},
|
||||
|
||||
stop: function () {
|
||||
api.put('stop')
|
||||
},
|
||||
|
||||
step: function () {
|
||||
api.put('step')
|
||||
},
|
||||
|
||||
override_feed: function () {
|
||||
api.put('override/feed/' + this.feed_override)
|
||||
},
|
||||
|
||||
override_speed: function () {
|
||||
api.put('override/speed/' + this.speed_override)
|
||||
},
|
||||
|
||||
|
||||
current: function (axis, value) {
|
||||
var x = value / 32.0;
|
||||
if (this.state[axis + 'pl'] == x) return;
|
||||
if (this.state[axis + 'pl'] == x) {
|
||||
return;
|
||||
}
|
||||
|
||||
var data = {};
|
||||
data[axis + 'pl'] = x;
|
||||
this.send(JSON.stringify(data));
|
||||
},
|
||||
|
||||
showProbeDialog: function(probeType) {
|
||||
SvelteComponents.showDialog("Probe", { probeType });
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
mixins: [require('./axis-vars')]
|
||||
}
|
||||
|
||||
114
src/js/main.js
114
src/js/main.js
@@ -1,33 +1,5 @@
|
||||
/******************************************************************************\
|
||||
|
||||
This file is part of the Buildbotics firmware.
|
||||
|
||||
Copyright (c) 2015 - 2018, Buildbotics LLC
|
||||
All rights reserved.
|
||||
|
||||
This file ("the software") is free software: you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License,
|
||||
version 2 as published by the Free Software Foundation. You should
|
||||
have received a copy of the GNU General Public License, version 2
|
||||
along with the software. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
The software is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the software. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
For information regarding this software email:
|
||||
"Joseph Coffland" <joseph@buildbotics.com>
|
||||
|
||||
\******************************************************************************/
|
||||
|
||||
'use strict';
|
||||
|
||||
|
||||
function cookie_get(name) {
|
||||
var decodedCookie = decodeURIComponent(document.cookie);
|
||||
var ca = decodedCookie.split(';');
|
||||
@@ -35,12 +7,16 @@ function cookie_get(name) {
|
||||
|
||||
for (var i = 0; i < ca.length; i++) {
|
||||
var c = ca[i];
|
||||
while (c.charAt(0) == ' ') c = c.substring(1);
|
||||
if (!c.indexOf(name)) return c.substring(name.length, c.length);
|
||||
while (c.charAt(0) == ' ') {
|
||||
c = c.substring(1);
|
||||
}
|
||||
|
||||
if (!c.indexOf(name)) {
|
||||
return c.substring(name.length, c.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function cookie_set(name, value, days) {
|
||||
var d = new Date();
|
||||
d.setTime(d.getTime() + days * 24 * 60 * 60 * 1000);
|
||||
@@ -48,29 +24,26 @@ function cookie_set(name, value, days) {
|
||||
document.cookie = name + '=' + value + ';' + expires + ';path=/';
|
||||
}
|
||||
|
||||
|
||||
var uuid_chars =
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_+';
|
||||
|
||||
var uuid_chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_+';
|
||||
|
||||
function uuid(length) {
|
||||
if (typeof length == 'undefined') length = 52;
|
||||
if (typeof length == 'undefined') {
|
||||
length = 52;
|
||||
}
|
||||
|
||||
var s = '';
|
||||
for (var i = 0; i < length; i++)
|
||||
for (var i = 0; i < length; i++) {
|
||||
s += uuid_chars[Math.floor(Math.random() * uuid_chars.length)];
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
|
||||
$(function() {
|
||||
if (typeof cookie_get('client-id') == 'undefined')
|
||||
$(function () {
|
||||
if (typeof cookie_get('client-id') == 'undefined') {
|
||||
cookie_set('client-id', uuid(), 10000);
|
||||
|
||||
// Vue debugging
|
||||
Vue.config.debug = true;
|
||||
//Vue.util.warn = function (msg) {console.debug('[Vue warn]: ' + msg)}
|
||||
}
|
||||
|
||||
// Register global components
|
||||
Vue.component('templated-input', require('./templated-input'));
|
||||
@@ -81,38 +54,64 @@ $(function() {
|
||||
Vue.component('unit-value', require('./unit-value'));
|
||||
|
||||
Vue.filter('number', function (value) {
|
||||
if (isNaN(value)) return 'NaN';
|
||||
if (isNaN(value)) {
|
||||
return 'NaN';
|
||||
}
|
||||
|
||||
return value.toLocaleString();
|
||||
});
|
||||
|
||||
Vue.filter('percent', function (value, precision) {
|
||||
if (typeof value == 'undefined') return '';
|
||||
if (typeof precision == 'undefined') precision = 2;
|
||||
if (typeof value == 'undefined') {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (typeof precision == 'undefined') {
|
||||
precision = 2;
|
||||
}
|
||||
|
||||
return (value * 100.0).toFixed(precision) + '%';
|
||||
});
|
||||
|
||||
Vue.filter('non_zero_percent', function (value, precision) {
|
||||
if (!value) return '';
|
||||
if (typeof precision == 'undefined') precision = 2;
|
||||
if (!value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (typeof precision == 'undefined') {
|
||||
precision = 2;
|
||||
}
|
||||
|
||||
return (value * 100.0).toFixed(precision) + '%';
|
||||
});
|
||||
|
||||
Vue.filter('fixed', function (value, precision) {
|
||||
if (typeof value == 'undefined') return '0';
|
||||
if (typeof value == 'undefined') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
return parseFloat(value).toFixed(precision)
|
||||
});
|
||||
|
||||
Vue.filter('upper', function (value) {
|
||||
if (typeof value == 'undefined') return '';
|
||||
if (typeof value == 'undefined') {
|
||||
return '';
|
||||
}
|
||||
|
||||
return value.toUpperCase()
|
||||
});
|
||||
|
||||
Vue.filter('time', function (value, precision) {
|
||||
if (isNaN(value)) return '';
|
||||
if (isNaN(precision)) precision = 0;
|
||||
if (isNaN(value)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (isNaN(precision)) {
|
||||
precision = 0;
|
||||
}
|
||||
|
||||
var MIN = 60;
|
||||
var HR = MIN * 60;
|
||||
var HR = MIN * 60;
|
||||
var DAY = HR * 24;
|
||||
var parts = [];
|
||||
|
||||
@@ -129,14 +128,17 @@ $(function() {
|
||||
if (MIN <= value) {
|
||||
parts.push(Math.floor(value / MIN));
|
||||
value %= MIN;
|
||||
|
||||
} else parts.push(0);
|
||||
} else {
|
||||
parts.push(0);
|
||||
}
|
||||
|
||||
parts.push(value);
|
||||
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
parts[i] = parts[i].toFixed(i == parts.length - 1 ? precision : 0);
|
||||
if (i && parts[i] < 10) parts[i] = '0' + parts[i];
|
||||
if (i && parts[i] < 10) {
|
||||
parts[i] = '0' + parts[i];
|
||||
}
|
||||
}
|
||||
|
||||
return parts.join(':');
|
||||
|
||||
@@ -1,124 +1,105 @@
|
||||
/******************************************************************************\
|
||||
|
||||
This file is part of the Buildbotics firmware.
|
||||
|
||||
Copyright (c) 2015 - 2018, Buildbotics LLC
|
||||
All rights reserved.
|
||||
|
||||
This file ("the software") is free software: you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License,
|
||||
version 2 as published by the Free Software Foundation. You should
|
||||
have received a copy of the GNU General Public License, version 2
|
||||
along with the software. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
The software is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the software. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
For information regarding this software email:
|
||||
"Joseph Coffland" <joseph@buildbotics.com>
|
||||
|
||||
\******************************************************************************/
|
||||
|
||||
'use strict'
|
||||
|
||||
|
||||
module.exports = {
|
||||
template: '#motor-view-template',
|
||||
props: ['index', 'config', 'template', 'state'],
|
||||
|
||||
|
||||
computed: {
|
||||
metric: function () {return this.$root.metric()},
|
||||
|
||||
metric: function () {
|
||||
return this.$root.display_units === "METRIC";
|
||||
},
|
||||
|
||||
is_slave: function () {
|
||||
for (var i = 0; i < this.index; i++)
|
||||
if (this.motor.axis == this.config.motors[i].axis)
|
||||
for (var i = 0; i < this.index; i++) {
|
||||
if (this.motor.axis == this.config.motors[i].axis) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
|
||||
motor: function () {return this.config.motors[this.index]},
|
||||
|
||||
motor: function () {
|
||||
return this.config.motors[this.index]
|
||||
},
|
||||
|
||||
invalidMaxVelocity: function () {
|
||||
return this.maxMaxVelocity < this.motor['max-velocity'];
|
||||
},
|
||||
|
||||
|
||||
maxMaxVelocity: function () {
|
||||
return 1 * (15 * this.umPerStep / this.motor['microsteps']).toFixed(3);
|
||||
},
|
||||
|
||||
|
||||
ustepPerSec: function () {
|
||||
return this.rpm * this.stepsPerRev * this.motor['microsteps'] / 60;
|
||||
},
|
||||
|
||||
|
||||
rpm: function () {
|
||||
return 1000 * this.motor['max-velocity'] / this.motor['travel-per-rev'];
|
||||
},
|
||||
|
||||
gForce: function () {
|
||||
return this.motor['max-accel'] * 0.0283254504
|
||||
},
|
||||
|
||||
gForce: function () {return this.motor['max-accel'] * 0.0283254504},
|
||||
gForcePerMin: function () {return this.motor['max-jerk'] * 0.0283254504},
|
||||
stepsPerRev: function () {return 360 / this.motor['step-angle']},
|
||||
gForcePerMin: function () {
|
||||
return this.motor['max-jerk'] * 0.0283254504
|
||||
},
|
||||
|
||||
stepsPerRev: function () {
|
||||
return 360 / this.motor['step-angle']
|
||||
},
|
||||
|
||||
umPerStep: function () {
|
||||
return this.motor['travel-per-rev'] * this.motor['step-angle'] / 0.36
|
||||
},
|
||||
|
||||
milPerStep: function () {
|
||||
return this.umPerStep / 25.4
|
||||
},
|
||||
|
||||
milPerStep: function () {return this.umPerStep / 25.4},
|
||||
invalidStallVelocity: function () {
|
||||
if (!this.motor['homing-mode'].startsWith('stall-')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
invalidStallVelocity: function() {
|
||||
if(!this.motor['homing-mode'].startsWith('stall-')) return false;
|
||||
return this.maxStallVelocity < this.motor['search-velocity'];
|
||||
},
|
||||
|
||||
stallRPM: function() {
|
||||
stallRPM: function () {
|
||||
var v = this.motor['search-velocity'];
|
||||
return 1000 * v / this.motor['travel-per-rev'];
|
||||
},
|
||||
|
||||
maxStallVelocity: function() {
|
||||
var maxRate = 900000/this.motor['stall-sample-time'];
|
||||
maxStallVelocity: function () {
|
||||
var maxRate = 900000 / this.motor['stall-sample-time'];
|
||||
var ustep = this.motor['stall-microstep'];
|
||||
var angle = this.motor['step-angle'];
|
||||
var travel = this.motor['travel-per-rev'];
|
||||
var maxStall = maxRate * 60/ 360 /1000 * angle/ ustep * travel;
|
||||
var maxStall = maxRate * 60 / 360 / 1000 * angle / ustep * travel;
|
||||
|
||||
return 1 * maxStall.toFixed(3);
|
||||
},
|
||||
|
||||
stallUStepPerSec: function() {
|
||||
stallUStepPerSec: function () {
|
||||
var ustep = this.motor['stall-microstep'];
|
||||
return this.stallRPM * this.stepsPerRev * ustep / 60;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
|
||||
events: {
|
||||
'input-changed': function() {
|
||||
'input-changed': function () {
|
||||
Vue.nextTick(function () {
|
||||
// Limit max-velocity
|
||||
if (this.invalidMaxVelocity)
|
||||
if (this.invalidMaxVelocity) {
|
||||
this.$set('motor["max-velocity"]', this.maxMaxVelocity);
|
||||
}
|
||||
|
||||
//Limit stall-velocity
|
||||
if(this.invalidStallVelocity)
|
||||
if (this.invalidStallVelocity) {
|
||||
this.$set('motor["search-velocity"]', this.maxStallVelocity);
|
||||
}
|
||||
|
||||
this.$dispatch('config-changed');
|
||||
}.bind(this))
|
||||
@@ -128,8 +109,11 @@ module.exports = {
|
||||
},
|
||||
|
||||
methods: {
|
||||
show: function(name, templ) {
|
||||
if(templ.hmodes == undefined) return true;
|
||||
show: function (name, templ) {
|
||||
if (templ.hmodes == undefined) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return templ.hmodes.indexOf(this.motor['homing-mode']) != -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,40 +1,23 @@
|
||||
/******************************************************************************\
|
||||
|
||||
This file is part of the Buildbotics firmware.
|
||||
|
||||
Copyright (c) 2015 - 2018, Buildbotics LLC
|
||||
All rights reserved.
|
||||
|
||||
This file ("the software") is free software: you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License,
|
||||
version 2 as published by the Free Software Foundation. You should
|
||||
have received a copy of the GNU General Public License, version 2
|
||||
along with the software. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
The software is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the software. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
For information regarding this software email:
|
||||
"Joseph Coffland" <joseph@buildbotics.com>
|
||||
|
||||
\******************************************************************************/
|
||||
|
||||
'use strict'
|
||||
|
||||
|
||||
module.exports = {
|
||||
template: '#settings-view-template',
|
||||
props: ['config', 'template'],
|
||||
|
||||
computed: {
|
||||
display_units: {
|
||||
cache: false,
|
||||
get: function () {
|
||||
return this.$root.display_units;
|
||||
},
|
||||
set: function (value) {
|
||||
this.$root.display_units = value;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
events: {
|
||||
'input-changed': function() {
|
||||
'input-changed': function () {
|
||||
this.$dispatch('config-changed');
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,49 +1,24 @@
|
||||
/******************************************************************************\
|
||||
|
||||
This file is part of the Buildbotics firmware.
|
||||
|
||||
Copyright (c) 2015 - 2018, Buildbotics LLC
|
||||
All rights reserved.
|
||||
|
||||
This file ("the software") is free software: you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License,
|
||||
version 2 as published by the Free Software Foundation. You should
|
||||
have received a copy of the GNU General Public License, version 2
|
||||
along with the software. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
The software is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the software. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
For information regarding this software email:
|
||||
"Joseph Coffland" <joseph@buildbotics.com>
|
||||
|
||||
\******************************************************************************/
|
||||
|
||||
'use strict'
|
||||
|
||||
|
||||
module.exports = {
|
||||
replace: true,
|
||||
template: '#templated-input-template',
|
||||
props: ['name', 'model', 'template'],
|
||||
|
||||
|
||||
data: function () {return {view: ''}},
|
||||
|
||||
data: function () {
|
||||
return { view: '' }
|
||||
},
|
||||
|
||||
computed: {
|
||||
metric: function () {return this.$root.metric()},
|
||||
|
||||
metric: function () {
|
||||
return this.$root.display_units === "METRIC";
|
||||
},
|
||||
|
||||
_view: function () {
|
||||
if (this.template.scale) {
|
||||
if (this.metric) return 1 * this.model.toFixed(3);
|
||||
if (this.metric) {
|
||||
return 1 * this.model.toFixed(3);
|
||||
}
|
||||
|
||||
return 1 * (this.model / this.template.scale).toFixed(4);
|
||||
}
|
||||
@@ -51,39 +26,44 @@ module.exports = {
|
||||
return this.model;
|
||||
},
|
||||
|
||||
|
||||
units: function () {
|
||||
return (this.metric || !this.template.iunit) ?
|
||||
this.template.unit : this.template.iunit;
|
||||
return (this.metric || !this.template.iunit)
|
||||
? this.template.unit
|
||||
: this.template.iunit;
|
||||
},
|
||||
|
||||
|
||||
title: function () {
|
||||
var s = 'Default ' + this.template.default + ' ' +
|
||||
(this.template.unit || '');
|
||||
if (typeof this.template.help != 'undefined')
|
||||
var s = `Default :${this.template.default} ${(this.template.unit || '')}`;
|
||||
|
||||
if (typeof this.template.help != 'undefined') {
|
||||
s = this.template.help + '\n' + s;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
watch: {
|
||||
_view: function () {this.view = this._view},
|
||||
|
||||
_view: function () {
|
||||
this.view = this._view
|
||||
},
|
||||
|
||||
view: function () {
|
||||
if (this.template.scale && !this.metric)
|
||||
if (this.template.scale && !this.metric) {
|
||||
this.model = this.view * this.template.scale;
|
||||
else this.model = this.view;
|
||||
} else {
|
||||
this.model = this.view;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
ready: function () {this.view = this._view},
|
||||
|
||||
ready: function () {
|
||||
this.view = this._view
|
||||
},
|
||||
|
||||
methods: {
|
||||
change: function () {this.$dispatch('input-changed')}
|
||||
change: function () {
|
||||
this.$dispatch('input-changed')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,58 +1,47 @@
|
||||
/******************************************************************************\
|
||||
|
||||
This file is part of the Buildbotics firmware.
|
||||
|
||||
Copyright (c) 2015 - 2018, Buildbotics LLC
|
||||
All rights reserved.
|
||||
|
||||
This file ("the software") is free software: you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License,
|
||||
version 2 as published by the Free Software Foundation. You should
|
||||
have received a copy of the GNU General Public License, version 2
|
||||
along with the software. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
The software is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the software. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
For information regarding this software email:
|
||||
"Joseph Coffland" <joseph@buildbotics.com>
|
||||
|
||||
\******************************************************************************/
|
||||
|
||||
'use strict'
|
||||
|
||||
|
||||
module.exports = {
|
||||
replace: true,
|
||||
template: '{{text}}<span class="unit">{{metric ? unit : iunit}}</span>',
|
||||
props: ['value', 'precision', 'unit', 'iunit', 'scale'],
|
||||
|
||||
|
||||
computed: {
|
||||
metric: function () {return !this.$root.state.imperial},
|
||||
|
||||
metric: {
|
||||
cache: false,
|
||||
get: function () {
|
||||
return this.$root.display_units === "METRIC";
|
||||
}
|
||||
},
|
||||
|
||||
text: function () {
|
||||
var value = this.value;
|
||||
if (typeof value == 'undefined') return '';
|
||||
if (typeof value == 'undefined') {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (!this.metric) value /= this.scale;
|
||||
if (!this.metric) {
|
||||
value /= this.scale;
|
||||
}
|
||||
|
||||
return (1 * value.toFixed(this.precision)).toLocaleString();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
ready: function () {
|
||||
if (typeof this.precision == 'undefined') this.precision = 0;
|
||||
if (typeof this.unit == 'undefined') this.unit = 'mm';
|
||||
if (typeof this.iunit == 'undefined') this.iunit = 'in';
|
||||
if (typeof this.scale == 'undefined') this.scale = 25.4;
|
||||
if (typeof this.precision == 'undefined') {
|
||||
this.precision = 0;
|
||||
}
|
||||
|
||||
if (typeof this.unit == 'undefined') {
|
||||
this.unit = 'mm';
|
||||
}
|
||||
|
||||
if (typeof this.iunit == 'undefined') {
|
||||
this.iunit = 'in';
|
||||
}
|
||||
|
||||
if (typeof this.scale == 'undefined') {
|
||||
this.scale = 25.4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,30 +1,3 @@
|
||||
//-/////////////////////////////////////////////////////////////////////////////
|
||||
//- //
|
||||
//- This file is part of the Buildbotics firmware. //
|
||||
//- //
|
||||
//- Copyright (c) 2015 - 2018, Buildbotics LLC //
|
||||
//- All rights reserved. //
|
||||
//- //
|
||||
//- This file ("the software") is free software: you can redistribute it //
|
||||
//- and/or modify it under the terms of the GNU General Public License, //
|
||||
//- version 2 as published by the Free Software Foundation. You should //
|
||||
//- have received a copy of the GNU General Public License, version 2 //
|
||||
//- along with the software. If not, see <http://www.gnu.org/licenses/>. //
|
||||
//- //
|
||||
//- The software is distributed in the hope that it will be useful, but //
|
||||
//- WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
|
||||
//- Lesser General Public License for more details. //
|
||||
//- //
|
||||
//- You should have received a copy of the GNU Lesser General Public //
|
||||
//- License along with the software. If not, see //
|
||||
//- <http://www.gnu.org/licenses/>. //
|
||||
//- //
|
||||
//- For information regarding this software email: //
|
||||
//- "Joseph Coffland" <joseph@buildbotics.com> //
|
||||
//- //
|
||||
//-/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
script#control-view-template(type="text/x-template")
|
||||
#control
|
||||
message(:show.sync="showGcodeMessage")
|
||||
@@ -63,70 +36,6 @@ script#control-view-template(type="text/x-template")
|
||||
button.pure-button(@click='ask_zero_z_msg = false')
|
||||
| Cancel
|
||||
|
||||
message(:show.sync=`show_probe_test_modal`)
|
||||
|
||||
h3(slot="header") Test probe connection
|
||||
|
||||
div(slot="body")
|
||||
.pure-form
|
||||
p Attach the probe magnet to the collet.
|
||||
p Touch the probe block to the bit.
|
||||
|
||||
div(slot="footer")
|
||||
button.pure-button(@click=`show_probe_test_modal = false`)
|
||||
| Cancel
|
||||
|
||||
button.pure-button.button-success(
|
||||
:disabled=`!state.saw_probe_connected`
|
||||
@click=`finish_probe_test()`) Continue
|
||||
|
||||
message(:show.sync=`show_tool_diameter_modal`)
|
||||
h3(slot="header") Enter probe tool information
|
||||
|
||||
div(slot="body")
|
||||
.pure-form
|
||||
.pure-control-group
|
||||
label="{{metric ? 'Diameter (mm)' : 'Diameter (inches)'}}"
|
||||
input(v-model="tool_diameter_for_prompt", size="8")
|
||||
p
|
||||
|
||||
div(slot="footer")
|
||||
button.pure-button(@click=`show_tool_diameter_modal = false`)
|
||||
| Cancel
|
||||
|
||||
button.pure-button.button-success(
|
||||
@click=`set_tool_diameter`)
|
||||
| Set
|
||||
|
||||
message(:show.sync=`state.show_probe_complete_modal`)
|
||||
h3(slot="header") Probing complete!
|
||||
|
||||
div(slot="body")
|
||||
.pure-form
|
||||
p Don't forget to put away the probe!
|
||||
div(v-if="state.goto_xy_zero_after_probe")
|
||||
p
|
||||
| The machine will now move
|
||||
br
|
||||
| to the X-Y zero point.
|
||||
p Watch your hands!
|
||||
|
||||
div(slot="footer")
|
||||
button.pure-button.button-success(@click=`$emit("finalize_probe")`)
|
||||
| Done
|
||||
|
||||
message(:show.sync=`state.show_probe_failed_modal`)
|
||||
h3(slot="header") Probing failed!
|
||||
|
||||
div(slot="body")
|
||||
.pure-form
|
||||
p Could not find the probe block during probing!
|
||||
p Make sure the tip of the bit is about 1/4" (~6mm) above the probe block, and try again.
|
||||
|
||||
div(slot="footer")
|
||||
button.pure-button.button-success(@click=`hide_probe_failed_modal()`)
|
||||
| OK
|
||||
|
||||
table(style="table-layout: fixed; width: 100%;")
|
||||
tr(style="height: fit-content;")
|
||||
td(style="white-space: nowrap; width: 410px;", rowspan="2")
|
||||
@@ -138,55 +47,60 @@ script#control-view-template(type="text/x-template")
|
||||
col(style="width:100px")
|
||||
tr
|
||||
td(style="height:100px",align="center")
|
||||
button(style="height:100px;width:100px",@click="jog_fn(-1,1,0,0)")
|
||||
button(@click="jog_fn(-1,1,0,0)")
|
||||
.fa.fa-arrow-right(style="transform: rotate(-135deg);")
|
||||
td(style="height:100px",align="center")
|
||||
button(style="height:100px;width:100px",@click="jog_fn(0,1,0,0)") Y+
|
||||
button(@click="jog_fn(0,1,0,0)") Y+
|
||||
td(style="height:100px",align="center")
|
||||
button(style="height:100px;width:100px",@click="jog_fn(1,1,0,0)")
|
||||
button(@click="jog_fn(1,1,0,0)")
|
||||
.fa.fa-arrow-right(style="transform: rotate(-45deg);")
|
||||
td(style="height:100px",align="center")
|
||||
button(style="height:100px;width:100px",,@click="jog_fn(0,0,1,0)") Z+
|
||||
button(,@click="jog_fn(0,0,1,0)") Z+
|
||||
tr
|
||||
td(style="height:100px",align="center")
|
||||
button(style="height:100px;width:100px",@click="jog_fn(-1,0,0,0)") X-
|
||||
button(@click="jog_fn(-1,0,0,0)") X-
|
||||
td(style="height:100px",align="center")
|
||||
button(style="height:100px;width:100px",@click="ask_zero_xy_msg = true")
|
||||
button(@click="ask_zero_xy_msg = true")
|
||||
.fa.fa-bullseye(style="font-size: 172%")
|
||||
td(style="height:100px",align="center")
|
||||
button(style="height:100px;width:100px",@click="jog_fn(1,0,0,0)") X+
|
||||
button(@click="jog_fn(1,0,0,0)") X+
|
||||
td(style="height:100px",align="center")
|
||||
button(style="height:100px;width:100px",@click='ask_zero_z_msg = true') Z0
|
||||
button(@click='ask_zero_z_msg = true') Z0
|
||||
tr
|
||||
td(style="height:100px",align="center")
|
||||
button(style="height:100px;width:100px",@click="jog_fn(-1,-1,0,0)")
|
||||
button(@click="jog_fn(-1,-1,0,0)")
|
||||
.fa.fa-arrow-right(style="transform: rotate(135deg);")
|
||||
td(style="height:100px",align="center")
|
||||
button(style="height:100px;width:100px",@click="jog_fn(0,-1,0,0)") Y-
|
||||
button(@click="jog_fn(0,-1,0,0)") Y-
|
||||
td(style="height:100px",align="center")
|
||||
button(style="height:100px;width:100px",@click="jog_fn(1,-1,0,0)")
|
||||
button(@click="jog_fn(1,-1,0,0)")
|
||||
.fa.fa-arrow-right(style="transform: rotate(45deg);")
|
||||
td(style="height:100px",align="center")
|
||||
button(style="height:100px;width:100px",@click="jog_fn(0,0,-1,0)") Z-
|
||||
button(@click="jog_fn(0,0,-1,0)") Z-
|
||||
tr
|
||||
td(style="height:100px",align="center")
|
||||
button#jog_button_fine(style="height:100px;width:100px", @click=`set_jog_incr('fine')`) 0.1
|
||||
button(:style="getJogIncrFontWeight('fine')", @click="jog_incr = 'fine'")
|
||||
span {{jog_incr_amounts[display_units].fine}}#[span.jog-units {{metric ? 'mm' : 'in'}}]
|
||||
td(style="height:100px",align="center")
|
||||
button#jog_button_small(style="height:100px;width:100px", @click=`set_jog_incr('small')`) 1.0
|
||||
button(:style="getJogIncrFontWeight('small')", @click="jog_incr = 'small'")
|
||||
span {{jog_incr_amounts[display_units].small}}#[span.jog-units {{metric ? 'mm' : 'in'}}]
|
||||
td(style="height:100px",align="center")
|
||||
button#jog_button_medium(style="height:100px;width:100px", @click=`set_jog_incr('medium')`) 10
|
||||
button(:style="getJogIncrFontWeight('medium')", @click="jog_incr = 'medium'")
|
||||
span {{jog_incr_amounts[display_units].medium}}#[span.jog-units {{metric ? 'mm' : 'in'}}]
|
||||
td(style="height:100px",align="center")
|
||||
button#jog_button_large(style="height:100px;width:100px", @click=`set_jog_incr('large')`) 100
|
||||
button(:style="getJogIncrFontWeight('large')", @click="jog_incr = 'large'")
|
||||
span {{jog_incr_amounts[display_units].large}}#[span.jog-units {{metric ? 'mm' : 'in'}}]
|
||||
tr
|
||||
td(style="height:100px", align="center", colspan="2")
|
||||
button(:class="state['pw'] ? '' : 'load-on'",
|
||||
style="height:100px;width:200px",
|
||||
@click=`start_probe_test(prep_and_show_tool_diameter_modal)`)
|
||||
@click="showProbeDialog('xyz')")
|
||||
| Probe XYZ
|
||||
|
||||
td(style="height:100px", align="center", colspan="2")
|
||||
button(:class="state['pw'] ? '' : 'load-on'",
|
||||
style="height:100px;width:200px",
|
||||
@click=`start_probe_test(probe_z)`)
|
||||
@click="showProbeDialog('z')")
|
||||
| Probe Z
|
||||
|
||||
td(style="vertical-align: top;")
|
||||
@@ -198,8 +112,6 @@ script#control-view-template(type="text/x-template")
|
||||
th.offset Offset
|
||||
th.state State
|
||||
th.tstate Toolpath
|
||||
//th.tstate Min
|
||||
//th.tstate Max
|
||||
th.actions
|
||||
button.pure-button(disabled, style="height:60px;width:60px;display:none;")
|
||||
|
||||
@@ -224,8 +136,6 @@ script#control-view-template(type="text/x-template")
|
||||
td.tstate(:class=`${axis}.tklass`, :title=`${axis}.toolmsg`, @click=`show_toolpath_msg('${axis}')`)
|
||||
.fa(:class=`'fa-' + ${axis}.ticon`)
|
||||
| {{#{axis}.tstate}}
|
||||
//td.tstate: unit-value(:value=`${axis}.pathMin`, precision=4)
|
||||
//td.tstate: unit-value(:value=`${axis}.pathMax`, precision=4)
|
||||
|
||||
message(:show.sync=`toolpath_msg['${axis}']`)
|
||||
h3(slot="header") Tool path info {{'#{axis}' | upper}} axis
|
||||
@@ -310,10 +220,10 @@ script#control-view-template(type="text/x-template")
|
||||
td.message(:class="{attention: highlight_state}")
|
||||
| {{message.replace(/^#/, '')}}
|
||||
|
||||
tr(title="Active machine units")
|
||||
tr
|
||||
th Units
|
||||
td.mach_units
|
||||
select(v-model="mach_units", :disabled="!is_idle")
|
||||
td.units
|
||||
select(v-model="display_units")
|
||||
option(value="METRIC") METRIC
|
||||
option(value="IMPERIAL") IMPERIAL
|
||||
|
||||
@@ -471,6 +381,9 @@ script#control-view-template(type="text/x-template")
|
||||
|
||||
input(v-model="mdi", :disabled="!can_mdi", @keyup.enter="submit_mdi")
|
||||
|
||||
div
|
||||
em The machine is currently operating in #[strong {{mach_units}}] units. Use G20/G21 to switch units.
|
||||
|
||||
.history(:class="{placeholder: !history}")
|
||||
span(v-if="!history.length") MDI history displays here.
|
||||
ul
|
||||
|
||||
@@ -1,25 +1,3 @@
|
||||
//- All rights reserved. //
|
||||
//- //
|
||||
//- This file ("the software") is free software: you can redistribute it //
|
||||
//- and/or modify it under the terms of the GNU General Public License, //
|
||||
//- version 2 as published by the Free Software Foundation. You should //
|
||||
//- have received a copy of the GNU General Public License, version 2 //
|
||||
//- along with the software. If not, see <http://www.gnu.org/licenses/>. //
|
||||
//- //
|
||||
//- The software is distributed in the hope that it will be useful, but //
|
||||
//- WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
|
||||
//- Lesser General Public License for more details. //
|
||||
//- //
|
||||
//- You should have received a copy of the GNU Lesser General Public //
|
||||
//- License along with the software. If not, see //
|
||||
//- <http://www.gnu.org/licenses/>. //
|
||||
//- //
|
||||
//- For information regarding this software email: //
|
||||
//- "Joseph Coffland" <joseph@buildbotics.com> //
|
||||
//- //
|
||||
//-/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
script#settings-view-template(type="text/x-template")
|
||||
#settings
|
||||
h1 Settings
|
||||
@@ -27,13 +5,12 @@ script#settings-view-template(type="text/x-template")
|
||||
.pure-form.pure-form-aligned
|
||||
fieldset
|
||||
h2 Units
|
||||
templated-input(name="units", :model.sync="config.settings.units",
|
||||
:template="template.settings.units")
|
||||
.pure-control-group
|
||||
label(for="units") units
|
||||
select(name="units", v-model="display_units")
|
||||
option(value="METRIC") METRIC
|
||||
option(value="IMPERIAL") IMPERIAL
|
||||
|
||||
p
|
||||
| Note, #[tt units] sets both the machine default units and the
|
||||
| units used in motor configuration. GCode #[tt program-start],
|
||||
| set below, may also change the default machine units.
|
||||
|
||||
fieldset
|
||||
h2 Probing safety prompts
|
||||
|
||||
@@ -1,30 +1,3 @@
|
||||
//-/////////////////////////////////////////////////////////////////////////////
|
||||
//- //
|
||||
//- This file is part of the Buildbotics firmware. //
|
||||
//- //
|
||||
//- Copyright (c) 2015 - 2018, Buildbotics LLC //
|
||||
//- All rights reserved. //
|
||||
//- //
|
||||
//- This file ("the software") is free software: you can redistribute it //
|
||||
//- and/or modify it under the terms of the GNU General Public License, //
|
||||
//- version 2 as published by the Free Software Foundation. You should //
|
||||
//- have received a copy of the GNU General Public License, version 2 //
|
||||
//- along with the software. If not, see <http://www.gnu.org/licenses/>. //
|
||||
//- //
|
||||
//- The software is distributed in the hope that it will be useful, but //
|
||||
//- WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
//- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
|
||||
//- Lesser General Public License for more details. //
|
||||
//- //
|
||||
//- You should have received a copy of the GNU Lesser General Public //
|
||||
//- License along with the software. If not, see //
|
||||
//- <http://www.gnu.org/licenses/>. //
|
||||
//- //
|
||||
//- For information regarding this software email: //
|
||||
//- "Joseph Coffland" <joseph@buildbotics.com> //
|
||||
//- //
|
||||
//-/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
script#templated-input-template(type="text/x-template")
|
||||
.pure-control-group(class="tmpl-input-{{name}}", :title="title")
|
||||
label(:for="name") {{name}}
|
||||
|
||||
@@ -1,35 +1,6 @@
|
||||
################################################################################
|
||||
# #
|
||||
# This file is part of the Buildbotics firmware. #
|
||||
# #
|
||||
# Copyright (c) 2015 - 2018, Buildbotics LLC #
|
||||
# All rights reserved. #
|
||||
# #
|
||||
# This file ("the software") is free software: you can redistribute it #
|
||||
# and/or modify it under the terms of the GNU General Public License, #
|
||||
# version 2 as published by the Free Software Foundation. You should #
|
||||
# have received a copy of the GNU General Public License, version 2 #
|
||||
# along with the software. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# The software is distributed in the hope that it will be useful, but #
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU #
|
||||
# Lesser General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU Lesser General Public #
|
||||
# License along with the software. If not, see #
|
||||
# <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# For information regarding this software email: #
|
||||
# "Joseph Coffland" <joseph@buildbotics.com> #
|
||||
# #
|
||||
################################################################################
|
||||
|
||||
import os
|
||||
import time
|
||||
import bbctrl
|
||||
|
||||
|
||||
class Ctrl(object):
|
||||
def __init__(self, args, ioloop, id):
|
||||
self.args = args
|
||||
|
||||
@@ -82,9 +82,6 @@ class State(object):
|
||||
self.set_callback(str(i) + 'latch_velocity',
|
||||
lambda name, i = i: self.motor_latch_velocity(i))
|
||||
|
||||
#self.set_callback('metric', lambda name: 1 if self.is_metric() else 0)
|
||||
#self.set_callback('imperial', lambda name: 0 if self.is_metric() else 1)
|
||||
|
||||
self.reset()
|
||||
self.load_files()
|
||||
|
||||
@@ -100,11 +97,6 @@ class State(object):
|
||||
if not 'metric' in self.vars: self.set('metric', metric)
|
||||
if not 'imperial' in self.vars: self.set('imperial', not metric)
|
||||
|
||||
# Bit diameter for probing
|
||||
diameter = self.ctrl.config.get('probe-diameter', 6.35)
|
||||
self.log.info('INIT Diameter %f' % diameter)
|
||||
self.set('bitDiameter',diameter)
|
||||
|
||||
|
||||
def reset(self):
|
||||
# Unhome all motors
|
||||
|
||||
@@ -282,6 +282,12 @@ span.unit
|
||||
// The jogging buttons, etc.
|
||||
.control-buttons button
|
||||
font-size 150%
|
||||
width 100px
|
||||
height 100px
|
||||
|
||||
.jog-units
|
||||
font-size initial
|
||||
margin-left 5px
|
||||
|
||||
&:first-child
|
||||
margin 0.5em 0
|
||||
@@ -436,7 +442,7 @@ span.unit
|
||||
min-width 8em
|
||||
width 100%
|
||||
|
||||
.mach_units
|
||||
.units
|
||||
padding 0
|
||||
|
||||
select
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
<script lang="ts">
|
||||
import WifiConnectionDialog from "../dialogs/WifiConnectionDialog.svelte";
|
||||
import ChangeHostnameDialog from "../dialogs/ChangeHostnameDialog.svelte";
|
||||
import WifiConnectionDialog from "$dialogs/WifiConnectionDialog.svelte";
|
||||
import ChangeHostnameDialog from "$dialogs/ChangeHostnameDialog.svelte";
|
||||
import Button, { Label } from "@smui/button";
|
||||
import List, { Item, Graphic, Text, Meta } from "@smui/list";
|
||||
import Card from "@smui/card";
|
||||
import { networkInfo } from "../lib/NetworkInfo";
|
||||
import type { WifiNetwork } from "../lib/NetworkInfo";
|
||||
import { networkInfo, type WifiNetwork } from "$lib/NetworkInfo";
|
||||
|
||||
let changeHostnameDialog = {
|
||||
open: false,
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
<script lang="ts">
|
||||
import HomeMachineDialog from "../dialogs/HomeMachineDialog.svelte";
|
||||
import { HomeMachine } from "../lib/DialogProps";
|
||||
</script>
|
||||
|
||||
<HomeMachineDialog {...$HomeMachine} />
|
||||
@@ -2,8 +2,8 @@
|
||||
import Dialog, { Title, Content, Actions } from "@smui/dialog";
|
||||
import Button, { Label } from "@smui/button";
|
||||
import TextField from "@smui/textfield";
|
||||
import MessageDialog from "./MessageDialog.svelte";
|
||||
import * as api from "../lib/api";
|
||||
import MessageDialog from "$dialogs/MessageDialog.svelte";
|
||||
import * as api from "$lib/api";
|
||||
|
||||
// https://man7.org/linux/man-pages/man7/hostname.7.html
|
||||
//
|
||||
|
||||
38
src/svelte-components/src/dialogs/DialogHost.svelte
Normal file
38
src/svelte-components/src/dialogs/DialogHost.svelte
Normal file
@@ -0,0 +1,38 @@
|
||||
<script lang="ts" context="module">
|
||||
import HomeMachineDialog from "$dialogs/HomeMachineDialog.svelte";
|
||||
import ProbeDialog from "$dialogs/ProbeDialog.svelte";
|
||||
import {
|
||||
HomeMachineProps,
|
||||
ProbeProps,
|
||||
type HomeMachinePropsType,
|
||||
type ProbePropsType,
|
||||
} from "$dialogs/DialogProps";
|
||||
|
||||
export function showDialog(
|
||||
dialog: "HomeMachine",
|
||||
props: Omit<HomeMachinePropsType, "open">
|
||||
);
|
||||
|
||||
export function showDialog(
|
||||
dialog: "Probe",
|
||||
props: Omit<ProbePropsType, "open">
|
||||
);
|
||||
|
||||
export function showDialog(dialog: string, props: any) {
|
||||
switch (dialog) {
|
||||
case "HomeMachine":
|
||||
HomeMachineProps.set({ ...props, open: true });
|
||||
break;
|
||||
|
||||
case "Probe":
|
||||
ProbeProps.set({ ...props, open: true });
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error(`Unknown dialog '${dialog}`);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<HomeMachineDialog {...$HomeMachineProps} />
|
||||
<ProbeDialog {...$ProbeProps} />
|
||||
13
src/svelte-components/src/dialogs/DialogProps.ts
Normal file
13
src/svelte-components/src/dialogs/DialogProps.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { writable } from "svelte/store";
|
||||
|
||||
export const HomeMachineProps = writable<HomeMachinePropsType>();
|
||||
export type HomeMachinePropsType = {
|
||||
open: boolean,
|
||||
home: () => void
|
||||
}
|
||||
|
||||
export const ProbeProps = writable<ProbePropsType>();
|
||||
export type ProbePropsType = {
|
||||
open: boolean,
|
||||
probeType: "xyz" | "z"
|
||||
};
|
||||
293
src/svelte-components/src/dialogs/ProbeDialog.svelte
Normal file
293
src/svelte-components/src/dialogs/ProbeDialog.svelte
Normal file
@@ -0,0 +1,293 @@
|
||||
<script type="ts" context="module">
|
||||
import Dialog, { Title, Content, Actions } from "@smui/dialog";
|
||||
import Button, { Label } from "@smui/button";
|
||||
import { get, writable, type Writable } from "svelte/store";
|
||||
import { Config } from "$lib/ConfigStore";
|
||||
import { waitForChange } from "$lib/StoreHelpers";
|
||||
import { ControllerMethods } from "$lib/RegisterControllerMethods";
|
||||
import { tick } from "svelte";
|
||||
|
||||
type Stage =
|
||||
| "None"
|
||||
| "TestingProbe"
|
||||
| "TestingProbeComplete"
|
||||
| "GetToolDiameter"
|
||||
| "Probing"
|
||||
| "ProbingFailed"
|
||||
| "ProbingComplete";
|
||||
|
||||
const cancelled = writable(false);
|
||||
const probingActive = writable(false);
|
||||
const probeContacted = writable(false);
|
||||
const probingStarted = writable(false);
|
||||
const probingFailed = writable(false);
|
||||
const probingComplete = writable(false);
|
||||
const userAcknowledged = writable(false);
|
||||
|
||||
export function handleControllerStateUpdate(state: Record<string, any>) {
|
||||
if (!get(probingActive)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (true) {
|
||||
case state.pw === 0:
|
||||
probeContacted.set(true);
|
||||
break;
|
||||
|
||||
case state.log?.msg === "Switch not found":
|
||||
probingFailed.set(true);
|
||||
break;
|
||||
|
||||
case state.cycle !== "idle":
|
||||
probingStarted.set(true);
|
||||
break;
|
||||
|
||||
case state.cycle === "idle":
|
||||
if (get(probingStarted)) {
|
||||
probingStarted.set(false);
|
||||
probingComplete.set(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script type="ts">
|
||||
export let open;
|
||||
export let probeType: "xyz" | "z";
|
||||
let stage: Stage = "None";
|
||||
let toolDiameter;
|
||||
let confirmButton = {
|
||||
label: "Continue",
|
||||
disabled: false,
|
||||
allowClose: false,
|
||||
};
|
||||
|
||||
$: showPrompts = $Config.settings?.["probing-prompts"];
|
||||
$: clearFlags(stage);
|
||||
$: updateConfirmButton();
|
||||
|
||||
$: if (open) {
|
||||
// Svelte appears not to like it when you invoke
|
||||
// an async function from a reactive statement
|
||||
requestAnimationFrame(begin);
|
||||
}
|
||||
|
||||
function updateConfirmButton() {
|
||||
confirmButton.label = "Continue";
|
||||
confirmButton.disabled = false;
|
||||
confirmButton.allowClose = false;
|
||||
|
||||
switch (stage) {
|
||||
case "TestingProbe":
|
||||
case "Probing":
|
||||
confirmButton.disabled = true;
|
||||
break;
|
||||
|
||||
case "ProbingComplete":
|
||||
confirmButton.disabled = true;
|
||||
confirmButton.label = "Done";
|
||||
confirmButton.allowClose = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
async function begin() {
|
||||
try {
|
||||
$probingActive = true;
|
||||
|
||||
assertValidProbeType();
|
||||
|
||||
if (showPrompts) {
|
||||
stage = "TestingProbe";
|
||||
|
||||
await cancellableSignal(probeContacted);
|
||||
|
||||
stage = "TestingProbeComplete";
|
||||
await cancellableSignal(userAcknowledged);
|
||||
}
|
||||
|
||||
if (probeType === "xyz") {
|
||||
stage = "GetToolDiameter";
|
||||
await cancellableSignal(userAcknowledged);
|
||||
}
|
||||
|
||||
do {
|
||||
stage = "Probing";
|
||||
executeProbe(probeType, toolDiameter);
|
||||
|
||||
await cancellableSignal(probingComplete, probingFailed);
|
||||
|
||||
if ($probingFailed) {
|
||||
stage = "ProbingFailed";
|
||||
await cancellableSignal(userAcknowledged);
|
||||
}
|
||||
} while (!$probingComplete);
|
||||
|
||||
stage = "ProbingComplete";
|
||||
await cancellableSignal(userAcknowledged);
|
||||
|
||||
if (probeType === "xyz") {
|
||||
ControllerMethods.goto_zero(1, 1, 0, 0);
|
||||
}
|
||||
} catch (err) {
|
||||
if (err.message !== "cancelled") {
|
||||
console.error("Error during probing:", err);
|
||||
}
|
||||
} finally {
|
||||
$probingActive = false;
|
||||
stage = "None";
|
||||
clearFlags();
|
||||
}
|
||||
}
|
||||
|
||||
async function cancellableSignal<T>(...writables: Array<Writable<T>>) {
|
||||
await Promise.race([
|
||||
...writables.map((writable) => waitForChange(writable)),
|
||||
waitForChange(cancelled),
|
||||
]);
|
||||
|
||||
if ($cancelled) {
|
||||
throw new Error("cancelled");
|
||||
}
|
||||
}
|
||||
|
||||
function clearFlags(foo: string = "") {
|
||||
$cancelled = false;
|
||||
$probeContacted = false;
|
||||
$probingStarted = false;
|
||||
$probingFailed = false;
|
||||
$probingComplete = false;
|
||||
$userAcknowledged = false;
|
||||
}
|
||||
|
||||
function assertValidProbeType() {
|
||||
switch (probeType) {
|
||||
case "xyz":
|
||||
case "z":
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error(`Invalid probe type: ${probeType}`);
|
||||
}
|
||||
}
|
||||
|
||||
function executeProbe(probeType: "xyz" | "z", toolDiameter: number) {
|
||||
const probeBlockWidth = $Config.probe["probe-xdim"];
|
||||
const probeBlockLength = $Config.probe["probe-ydim"];
|
||||
const probeBlockHeight = $Config.probe["probe-zdim"];
|
||||
const slowSeek = $Config.probe["probe-slow-seek"];
|
||||
const fastSeek = $Config.probe["probe-fast-seek"];
|
||||
|
||||
const zLift = 1;
|
||||
const xOffset = probeBlockWidth + toolDiameter / 2.0;
|
||||
const yOffset = probeBlockLength + toolDiameter / 2.0;
|
||||
const zOffset = probeBlockHeight;
|
||||
|
||||
if (probeType === "z") {
|
||||
ControllerMethods.send(`
|
||||
G21
|
||||
G92 Z0
|
||||
|
||||
G38.2 Z -25.4 F${fastSeek}
|
||||
G91 G1 Z 1
|
||||
G38.2 Z -2 F${slowSeek}
|
||||
G92 Z ${zOffset}
|
||||
|
||||
G91 G0 Z 3
|
||||
|
||||
M2
|
||||
`);
|
||||
} else {
|
||||
// After probing Z, we want to drop the bit down:
|
||||
// Ideally, 12.7mm/0.5in
|
||||
// And we don't want to be more than 75% down on the probe block
|
||||
// Also, add zlift to compensate for the fact that we lift after probing Z
|
||||
const plunge = Math.min(12.7, zOffset * 0.75) + zLift;
|
||||
|
||||
ControllerMethods.send(`
|
||||
G21
|
||||
G92 X0 Y0 Z0
|
||||
|
||||
G38.2 Z -25 F${fastSeek}
|
||||
G91 G1 Z 1
|
||||
G38.2 Z -2 F${slowSeek}
|
||||
G92 Z ${zOffset}
|
||||
|
||||
G91 G0 Z ${zLift}
|
||||
G91 G0 X 20
|
||||
G91 G0 Z ${-plunge}
|
||||
G38.2 X -20 F${fastSeek}
|
||||
G91 G1 X 1
|
||||
G38.2 X -2 F${slowSeek}
|
||||
G92 X ${xOffset}
|
||||
|
||||
G91 G0 X 1
|
||||
G91 G0 Y 20
|
||||
G91 G0 X -20
|
||||
G38.2 Y -20 F${fastSeek}
|
||||
G91 G1 Y 1
|
||||
G38.2 Y -2 F${slowSeek}
|
||||
G92 Y ${yOffset}
|
||||
|
||||
G91 G0 Y 3
|
||||
G91 G0 Z 25
|
||||
|
||||
M2
|
||||
`);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<Dialog
|
||||
bind:open
|
||||
scrimClickAction=""
|
||||
aria-labelledby="simple-title"
|
||||
aria-describedby="simple-content"
|
||||
>
|
||||
<Title id="simple-title">Probe {probeType}</Title>
|
||||
|
||||
<Content id="simple-content">
|
||||
{#if stage === "TestingProbe" || stage === "TestingProbeComplete"}
|
||||
<p>Attach the probe magnet to the collet.</p>
|
||||
<p>Touch the probe block to the bit.</p>
|
||||
|
||||
{#if stage === "TestingProbe"}
|
||||
<p>Waiting for probe contact...</p>
|
||||
{:else}
|
||||
<p>Probe contact detected!</p>
|
||||
{/if}
|
||||
{:else if stage === "GetToolDiameter"}
|
||||
<label for="tool-diameter">Tool Diameter (mm)</label>
|
||||
<input id="tool-diameter" bind:value={toolDiameter} />
|
||||
{:else if stage === "Probing"}
|
||||
<p>Probing in progress...</p>
|
||||
{:else if stage === "ProbingFailed"}
|
||||
<p>Could not find the probe block during probing!</p>
|
||||
<p>
|
||||
Make sure the tip of the bit is about 1/4" (6mm) above the probe block,
|
||||
and try again.
|
||||
</p>
|
||||
{:else if stage === "ProbingComplete"}
|
||||
<p>Don't forget to put away the probe!</p>
|
||||
<p>The machine will now move to the XY origin.</p>
|
||||
<p>Watch your hands!</p>
|
||||
{/if}
|
||||
</Content>
|
||||
|
||||
<Actions>
|
||||
<Button on:click={() => ($cancelled = true)}>
|
||||
<Label>Cancel</Label>
|
||||
</Button>
|
||||
<Button
|
||||
defaultAction
|
||||
data-mdc-dialog-action={confirmButton.allowClose ? "close" : ""}
|
||||
disabled={confirmButton.disabled}
|
||||
on:click={() => ($userAcknowledged = true)}
|
||||
>
|
||||
<Label>
|
||||
{confirmButton.label}
|
||||
</Label>
|
||||
</Button>
|
||||
</Actions>
|
||||
</Dialog>
|
||||
@@ -4,28 +4,22 @@
|
||||
import TextField from "@smui/textfield";
|
||||
import Icon from "@smui/textfield/icon";
|
||||
import HelperText from "@smui/textfield/helper-text";
|
||||
import MessageDialog from "./MessageDialog.svelte";
|
||||
import type { WifiNetwork } from "../lib/NetworkInfo";
|
||||
import * as api from "../lib/api";
|
||||
import MessageDialog from "$dialogs/MessageDialog.svelte";
|
||||
import type { WifiNetwork } from "$lib/NetworkInfo";
|
||||
import * as api from "$lib/api";
|
||||
|
||||
export let open = false;
|
||||
export let network: WifiNetwork;
|
||||
|
||||
let rebooting = false;
|
||||
let needPassword = false;
|
||||
let password = "";
|
||||
let showPassword = false;
|
||||
let connectOrDisconnect: string;
|
||||
let connectToOrDisconnectFrom: string;
|
||||
|
||||
$: needPassword = !network?.active && network?.Encryption !== "Open";
|
||||
|
||||
$: {
|
||||
connectOrDisconnect = network?.active ? "Disconnect" : "Connect";
|
||||
connectToOrDisconnectFrom = network?.active
|
||||
$: connectOrDisconnect = network?.active ? "Disconnect" : "Connect";
|
||||
$: connectToOrDisconnectFrom = network?.active
|
||||
? "Disconnect from"
|
||||
: "Connect to";
|
||||
}
|
||||
|
||||
$: if (open) {
|
||||
password = "";
|
||||
|
||||
7
src/svelte-components/src/lib/ConfigStore.ts
Normal file
7
src/svelte-components/src/lib/ConfigStore.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { writable } from "svelte/store";
|
||||
|
||||
export const Config = writable<Record<string, any>>({});
|
||||
|
||||
export function handleConfigUpdate(config: Record<string, any>) {
|
||||
Config.set(config);
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import { writable } from "svelte/store";
|
||||
|
||||
type HomeMachine = {
|
||||
open: boolean,
|
||||
home: () => any
|
||||
}
|
||||
|
||||
export type DialogPropsTypes = {
|
||||
HomeMachine: HomeMachine
|
||||
}
|
||||
|
||||
export const HomeMachine = writable<HomeMachine>();
|
||||
|
||||
export default {
|
||||
HomeMachine
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
import { readable } from "svelte/store";
|
||||
import * as api from "./api";
|
||||
import * as api from "$lib/api";
|
||||
|
||||
export type WifiNetwork = {
|
||||
Quality: string;
|
||||
|
||||
10
src/svelte-components/src/lib/RegisterControllerMethods.ts
Normal file
10
src/svelte-components/src/lib/RegisterControllerMethods.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
type ControllerMethods = {
|
||||
send: (gcode: string) => void;
|
||||
goto_zero: (x: number, y: number, z: number, a: number) => void;
|
||||
}
|
||||
|
||||
export let ControllerMethods: ControllerMethods;
|
||||
|
||||
export function registerControllerMethods(methods: ControllerMethods) {
|
||||
ControllerMethods = methods;
|
||||
}
|
||||
18
src/svelte-components/src/lib/StoreHelpers.ts
Normal file
18
src/svelte-components/src/lib/StoreHelpers.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { get, type Writable } from "svelte/store";
|
||||
|
||||
export function listenForChange<T>(writable: Writable<T>, cb: (value: T) => void) {
|
||||
const priorValue = get(writable);
|
||||
|
||||
const unsubscribe = writable.subscribe((value) => {
|
||||
if (value !== priorValue) {
|
||||
unsubscribe();
|
||||
cb(value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function waitForChange<T>(writable: Writable<T>): Promise<T> {
|
||||
return new Promise((resolve) => {
|
||||
listenForChange(writable, (value) => resolve(value));
|
||||
});
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
import 'polyfill-object.fromentries';
|
||||
import AdminNetworkView from './components/AdminNetworkView.svelte';
|
||||
import { init as initNetworkInfo } from './lib/NetworkInfo';
|
||||
|
||||
import DialogHost from "./components/DialogHost.svelte";
|
||||
import DialogProps from "./lib/DialogProps";
|
||||
import type { DialogPropsTypes } from "./lib/DialogProps";
|
||||
import AdminNetworkView from '$components/AdminNetworkView.svelte';
|
||||
import DialogHost, { showDialog } from "$dialogs/DialogHost.svelte";
|
||||
import { handleConfigUpdate } from '$lib/ConfigStore';
|
||||
import { init as initNetworkInfo } from '$lib/NetworkInfo';
|
||||
import { handleControllerStateUpdate } from "$dialogs/ProbeDialog.svelte";
|
||||
import { registerControllerMethods } from "$lib/RegisterControllerMethods";
|
||||
|
||||
export function createComponent(component: string, target: HTMLElement, props: Record<string, any>) {
|
||||
switch (component) {
|
||||
@@ -19,17 +20,10 @@ export function createComponent(component: string, target: HTMLElement, props: R
|
||||
}
|
||||
}
|
||||
|
||||
export function showDialog<T extends keyof typeof DialogProps>(dialog: T, props: DialogPropsTypes[T]) {
|
||||
switch (dialog) {
|
||||
case "HomeMachine":
|
||||
DialogProps.HomeMachine.set({ ...props, open: true });
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error(`Unknown dialog '${dialog}`);
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
initNetworkInfo
|
||||
initNetworkInfo,
|
||||
showDialog,
|
||||
handleControllerStateUpdate,
|
||||
handleConfigUpdate,
|
||||
registerControllerMethods,
|
||||
};
|
||||
|
||||
@@ -6,6 +6,11 @@
|
||||
"module": "esnext",
|
||||
"resolveJsonModule": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"$lib/*": ["src/lib/*"],
|
||||
"$components/*": ["src/components/*"],
|
||||
"$dialogs/*": ["src/dialogs/*"]
|
||||
},
|
||||
/**
|
||||
* Typecheck JS in `.svelte` and `.js` files by default.
|
||||
* Disable checkJs if you'd like to use dynamic types in JS.
|
||||
|
||||
@@ -7,6 +7,13 @@ export default defineConfig({
|
||||
plugins: [
|
||||
svelte()
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
$lib: resolve('./src/lib'),
|
||||
$dialogs: resolve('./src/dialogs'),
|
||||
$components: resolve('./src/components')
|
||||
}
|
||||
},
|
||||
build: {
|
||||
target: "chrome60",
|
||||
lib: {
|
||||
|
||||
Reference in New Issue
Block a user