Rebuilt the network view in Svelte

This commit is contained in:
David Carley
2022-07-04 16:19:23 -07:00
parent 10df5ada62
commit 9710d56779
52 changed files with 11186 additions and 867 deletions

View File

@@ -1,36 +1,11 @@
/******************************************************************************\
"use strict";
This file is part of the Buildbotics firmware.
const api = require("./api");
const cookie = require("./cookie")("bbctrl-");
const Sock = require("./sock");
const omit = require("lodash.omit");
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'
const api = require('./api');
const cookie = require('./cookie')('bbctrl-');
const Sock = require('./sock');
const omit = require('lodash.omit');
SvelteComponents.initNetworkInfo();
function is_newer_version(current, latest) {
const pattern = /(\d+)\.(\d+)\.(\d+)(.*)/;
@@ -47,7 +22,8 @@ function is_newer_version(current, latest) {
const patch = latestParts[3] - currentParts[3];
// If current is a pre-release, and latest is a release
const betaToRelease = latestParts[4].length === 0 && currentParts[4].length > 0;
const betaToRelease =
latestParts[4].length === 0 && currentParts[4].length > 0;
switch (true) {
case major > 0:
@@ -61,15 +37,17 @@ function is_newer_version(current, latest) {
}
}
function is_object(o) { return o !== null && typeof o == 'object' }
function is_array(o) { return Array.isArray(o) }
function update_array(dst, src) {
while (dst.length) dst.pop()
for (var i = 0; i < src.length; i++)
Vue.set(dst, i, src[i]);
function is_object(o) {
return o !== null && typeof o == "object";
}
function is_array(o) {
return Array.isArray(o);
}
function update_array(dst, src) {
while (dst.length) dst.pop();
for (var i = 0; i < src.length; i++) Vue.set(dst, i, src[i]);
}
function update_object(dst, src, remove) {
var props, index, key, value;
@@ -79,8 +57,7 @@ function update_object(dst, src, remove) {
for (index in props) {
key = props[index];
if (!src.hasOwnProperty(key))
Vue.delete(dst, key);
if (!src.hasOwnProperty(key)) Vue.delete(dst, key);
}
}
@@ -91,111 +68,100 @@ function update_object(dst, src, remove) {
if (is_array(value) && dst.hasOwnProperty(key) && is_array(dst[key]))
update_array(dst[key], value);
else if (is_object(value) && dst.hasOwnProperty(key) && is_object(dst[key]))
update_object(dst[key], value, remove);
else Vue.set(dst, key, value);
}
}
module.exports = new Vue({
el: 'body',
el: "body",
data: function () {
return {
status: 'connecting',
currentView: 'loading',
status: "connecting",
currentView: "loading",
index: -1,
modified: false,
template: require('../resources/config-template.json'),
template: require("../resources/config-template.json"),
config: {
settings: { units: 'METRIC' },
settings: { units: "METRIC" },
motors: [{}, {}, {}, {}],
version: '<loading>',
full_version: '<loading>'
version: "<loading>",
full_version: "<loading>",
},
state: {
messages: [],
probing_active: false,
wait_for_probing_complete: false,
show_probe_complete_modal: false,
show_probe_failed_modal: false
show_probe_failed_modal: false,
},
video_size: cookie.get('video-size', 'small'),
crosshair: cookie.get('crosshair', 'false') != 'false',
video_size: cookie.get("video-size", "small"),
crosshair: cookie.get("crosshair", "false") != "false",
errorTimeout: 30,
errorTimeoutStart: 0,
errorShow: false,
errorMessage: '',
errorMessage: "",
confirmUpgrade: false,
confirmUpload: false,
firmwareUpgrading: false,
checkedUpgrade: false,
firmwareName: '',
latestVersion: '',
ipAddress: '0.0.0.0',
wifiSSID: '',
firmwareName: "",
latestVersion: "",
confirmShutdown: false,
diskSpace: ''
}
};
},
components: {
'estop': { template: '#estop-template' },
'loading-view': { template: '<h1>Loading...</h1>' },
'control-view': require('./control-view'),
'settings-view': require('./settings-view'),
'motor-view': require('./motor-view'),
'tool-view': require('./tool-view'),
'io-view': require('./io-view'),
'admin-general-view': require('./admin-general-view'),
'admin-network-view': require('./admin-network-view'),
'help-view': { template: '#help-view-template' },
'cheat-sheet-view': {
template: '#cheat-sheet-view-template',
data: function () { return { showUnimplemented: false } }
}
estop: { template: "#estop-template" },
"loading-view": { template: "<h1>Loading...</h1>" },
"control-view": require("./control-view"),
"settings-view": require("./settings-view"),
"motor-view": require("./motor-view"),
"tool-view": require("./tool-view"),
"io-view": require("./io-view"),
"admin-general-view": require("./admin-general-view"),
"admin-network-view": require("./admin-network-view"),
"help-view": { template: "#help-view-template" },
"cheat-sheet-view": {
template: "#cheat-sheet-view-template",
data: function () {
return { showUnimplemented: false };
},
},
},
events: {
'config-changed': function () {
"config-changed": function () {
this.modified = true;
},
'hostname-changed': function (hostname) {
this.hostname = hostname
},
send: function (msg) {
if (this.status == 'connected') {
console.debug('>', msg);
if (this.status == "connected") {
console.debug(">", msg);
this.sock.send(msg);
}
},
connected: function () {
this.update()
this.update();
},
update: function () {
this.update()
this.update();
},
check: function () {
this.latestVersion = '';
check: async function () {
try {
const response = await fetch("https://raw.githubusercontent.com/OneFinityCNC/onefinity-release/master/latest.txt", {
cache: "no-cache"
});
$.ajax({
type: 'GET',
url: 'https://raw.githubusercontent.com/OneFinityCNC/onefinity-release/master/latest.txt',
data: { hid: this.state.hid },
cache: false
}).done(function (data) {
this.latestVersion = data;
this.$broadcast('latest_version', data);
}.bind(this))
this.latestVersion = (await response.text()).trim();
} catch (err) {
this.latestVersion = "";
}
},
upgrade: function () {
@@ -221,7 +187,7 @@ module.exports = new Vue({
// Popup error dialog
this.errorShow = true;
this.errorMessage = msg.msg;
}
},
},
computed: {
@@ -236,17 +202,17 @@ module.exports = new Vue({
}
return msgs;
}
},
},
ready: function () {
$(window).on('hashchange', this.parse_hash);
$(window).on("hashchange", this.parse_hash);
this.connect();
},
methods: {
metric: function () {
return this.config.settings.units != 'IMPERIAL'
return this.config.settings.units != "IMPERIAL";
},
block_error_dialog: function () {
@@ -255,30 +221,30 @@ module.exports = new Vue({
},
toggle_video: function (e) {
if (this.video_size == 'small') this.video_size = 'large';
else if (this.video_size == 'large') this.video_size = 'small';
cookie.set('video-size', this.video_size);
if (this.video_size == "small") this.video_size = "large";
else if (this.video_size == "large") this.video_size = "small";
cookie.set("video-size", this.video_size);
},
toggle_crosshair: function (e) {
e.preventDefault();
this.crosshair = !this.crosshair;
cookie.set('crosshair', this.crosshair);
cookie.set("crosshair", this.crosshair);
},
estop: function () {
if (this.state.xx == 'ESTOPPED') api.put('clear');
else api.put('estop');
if (this.state.xx == "ESTOPPED") api.put("clear");
else api.put("estop");
},
upgrade_confirmed: async function () {
this.confirmUpgrade = false;
try {
await api.put('upgrade');
await api.put("upgrade");
this.firmwareUpgrading = true;
} catch (err) {
api.alert('Error during upgrade.');
api.alert("Error during upgrade.");
console.error("Error during upgrade", err);
}
},
@@ -287,22 +253,27 @@ module.exports = new Vue({
this.confirmUpload = false;
const form = new FormData();
form.append('firmware', this.firmware);
form.append("firmware", this.firmware);
$.ajax({
url: '/api/firmware/update',
type: 'PUT',
url: "/api/firmware/update",
type: "PUT",
data: form,
cache: false,
contentType: false,
processData: false
}).success(function () {
this.firmwareUpgrading = true;
}.bind(this)).error(function (err) {
api.alert('Firmware update failed');
console.error('Firmware update failed', err);
}.bind(this))
processData: false,
})
.success(
function () {
this.firmwareUpgrading = true;
}.bind(this)
)
.error(
function (err) {
api.alert("Firmware update failed");
console.error("Firmware update failed", err);
}.bind(this)
);
},
show_upgrade: function () {
@@ -310,97 +281,58 @@ module.exports = new Vue({
return is_newer_version(this.config.version, this.latestVersion);
},
update: function () {
api.get('config/load').done(function (config) {
update_object(this.config, config, true);
this.parse_hash();
update: async function () {
const config = await api.get("config/load");
if (!this.checkedUpgrade) {
this.checkedUpgrade = true;
update_object(this.config, config, true);
this.parse_hash();
var check = this.config.admin['auto-check-upgrade'];
if (typeof check == 'undefined' || check)
this.$emit('check');
}
if (!this.checkedUpgrade) {
this.checkedUpgrade = true;
this.check_ip_address();
this.check_ssid();
}.bind(this))
},
var check = this.config.admin["auto-check-upgrade"];
if (typeof check == "undefined" || check) this.$emit("check");
}
check_ip_address: function () {
$.ajax({
type: 'GET',
url: 'hostinfo.txt',
data: { hid: this.state.hid },
cache: false
}).done(function (data) {
console.debug('>', data);
this.ipAddress = 'IP:' + data;
this.$broadcast('ipAddress', data);
}.bind(this))
},
check_ssid: function () {
$.ajax({
type: 'GET',
url: 'ssidinfo.txt',
data: { hid: this.state.hid },
cache: false
}).done(function (data) {
console.debug('>', data);
this.wifiSSID = 'SSID:' + data;
this.$broadcast('wifiSSID', data);
}.bind(this))
},
get_ip_address: function () {
console.debug('get_ip>', this.ipAddress);
return this.ipAddress;
},
get_ssid: function () {
console.debug('get_ssid>', this.wifiSSID);
return this.wifiSSID;
},
shutdown: function () {
this.confirmShutdown = false;
api.put('shutdown');
api.put("shutdown");
},
reboot: function () {
this.confirmShutdown = false;
api.put('reboot');
api.put("reboot");
},
connect: function () {
this.sock = new Sock(`//${location.host}/sockjs`);
this.sock.onmessage = (e) => {
if (typeof e.data != 'object') {
if (typeof e.data != "object") {
return;
}
if ('log' in e.data) {
if ("log" in e.data) {
if (e.data.log.msg === "Switch not found") {
this.$broadcast('probing_failed');
this.$broadcast("probing_failed");
} else {
this.$broadcast('log', e.data.log);
this.$broadcast("log", e.data.log);
}
delete e.data.log;
}
// Check for session ID change on controller
if ('sid' in e.data) {
if (typeof this.sid == 'undefined') {
if ("sid" in e.data) {
if (typeof this.sid == "undefined") {
this.sid = e.data.sid;
} else if (this.sid != e.data.sid) {
if (typeof this.hostname !== 'undefined' && location.hostname !== 'localhost') {
if (
typeof this.hostname !== "undefined" &&
location.hostname !== "localhost"
) {
location.hostname = this.hostname;
}
@@ -412,15 +344,15 @@ module.exports = new Vue({
const debugStateChanges = false;
if (debugStateChanges) {
const data = omit(e.data, [
'vdd',
'vin',
'vout',
'motor',
'temp',
'heartbeat',
'load1',
'load2',
'rpi_temp'
"vdd",
"vin",
"vout",
"motor",
"temp",
"heartbeat",
"load1",
"load2",
"rpi_temp",
]);
if (Object.keys(data).length > 0) {
console.log(JSON.stringify(data, null, 4));
@@ -433,24 +365,24 @@ module.exports = new Vue({
Vue.set(this.state, "saw_probe_connected", true);
}
if (this.state.cycle === 'idle') {
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");
}
}
this.$broadcast('update');
this.$broadcast("update");
};
this.sock.onopen = () => {
this.status = 'connected';
this.status = "connected";
this.$emit(this.status);
this.$broadcast(this.status);
};
this.sock.onclose = () => {
this.status = 'disconnected';
this.status = "disconnected";
this.$emit(this.status);
this.$broadcast(this.status);
};
@@ -460,11 +392,11 @@ module.exports = new Vue({
var hash = location.hash.substr(1);
if (!hash.trim().length) {
location.hash = 'control';
location.hash = "control";
return;
}
var parts = hash.split(':');
var parts = hash.split(":");
if (parts.length == 2) this.index = parts[1];
@@ -472,35 +404,43 @@ module.exports = new Vue({
},
save: function () {
const selected_tool = this.config.tool['selected-tool'];
const saveModbus = selected_tool !== "pwm" &&
const selected_tool = this.config.tool["selected-tool"];
const saveModbus =
selected_tool !== "pwm" &&
selected_tool !== "laser" &&
selected_tool !== "router";
const settings = {
['tool']: { ...this.config.tool },
['pwm-spindle']: { ...this.config['pwm-spindle'] },
['modbus-spindle']: saveModbus ? { ...this.config['modbus-spindle'] } : undefined
}
delete settings.tool['tool-type'];
["tool"]: { ...this.config.tool },
["pwm-spindle"]: { ...this.config["pwm-spindle"] },
["modbus-spindle"]: saveModbus
? { ...this.config["modbus-spindle"] }
: undefined,
};
delete settings.tool["tool-type"];
this.config['selected-tool-settings'][selected_tool] = settings;
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);
});
api
.put("config/save", this.config)
.done(
function (data) {
this.modified = false;
}.bind(this)
)
.fail(function (error) {
api.alert("Save failed", error);
});
},
close_messages: function (action) {
if (action == 'stop') api.put('stop');
if (action == 'continue') api.put('unpause');
if (action == "stop") api.put("stop");
if (action == "continue") api.put("unpause");
// Acknowledge messages
if (this.state.messages.length) {
var id = this.state.messages.slice(-1)[0].id
api.put('message/' + id + '/ack');
var id = this.state.messages.slice(-1)[0].id;
api.put("message/" + id + "/ack");
}
}
}
})
},
},
});