Skip to content

Commit

Permalink
add tool fan, extrusion factor and speed factor to dashbaord; add mac…
Browse files Browse the repository at this point in the history
…ro buttons to dashboard; show printer stats in title & favicon
  • Loading branch information
meteyou committed Mar 26, 2020
1 parent 851c17a commit 54aaf8d
Show file tree
Hide file tree
Showing 22 changed files with 3,079 additions and 2,119 deletions.
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ Configure web_server in printer.cfg:
```
[web_server]
port: 8080
enable_cors: true
trusted_clients:
192.168.1.0/24
127.0.0.1
web_path: ~/kwc
```

Expand All @@ -34,6 +36,11 @@ gcode:
M141 S0
M106 S0
CLEAR_PAUSE
RESET_SD
[gcode_macro CANCEL_PRINT]
gcode:
CANCEL
[gcode_macro PAUSE]
rename_existing: BASE_PAUSE
Expand All @@ -60,6 +67,29 @@ gcode:
BASE_RESUME
```

## Installation haproxy
haproxy is necessary to use port 80.

`sudo apt install haproxy`

add following lines at the end of `/etc/haproxy/haproxy.cfg`:
```
frontend public
bind :::80 v4v6
# use_backend webcam if { path_beg /webcam/ }
default_backend kwc
backend kwc
reqrep ^([^\ :]*)\ /(.*)     \1\ /\2
option forwardfor
server kwc1 127.0.0.1:8080
#backend webcam
# reqrep ^([^\ :]*)\ /webcam/(.*) \1\ /\2
# server webcam1 127.0.0.1:8081
```


## Update KWC to V0.0.5
```
rm -R ~/kwc/*
Expand Down
3,676 changes: 2,041 additions & 1,635 deletions package-lock.json

Large diffs are not rendered by default.

36 changes: 18 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,37 +10,37 @@
"dependencies": {
"axios": "^0.19.2",
"chart.js": "^2.9.3",
"core-js": "^3.1.2",
"vue": "^2.6.10",
"core-js": "^3.6.4",
"vue": "^2.6.11",
"vue-chartjs": "^3.5.0",
"vue-context": "^5.0.0",
"vue-headful": "^2.1.0",
"vue-json-rpc-websocket": "^1.0.5",
"vue-json-rpc-websocket": "^1.1.1",
"vue-resource": "^1.5.1",
"vue-simple-upload": "^0.1.6",
"vue-toast-notification": "0.0.3",
"vuetify": "^2.1.0",
"vuetify": "^2.2.17",
"vuetify-toast-snackbar": "^0.6.1",
"vuex": "^3.1.1"
"vuex": "^3.1.3"
},
"devDependencies": {
"@fortawesome/fontawesome-free": "^5.12.0",
"@mdi/font": "^4.5.95",
"@vue/cli-plugin-babel": "^4.0.0",
"@vue/cli-plugin-eslint": "^4.0.0",
"@vue/cli-service": "^4.0.0",
"babel-eslint": "^10.0.1",
"css-loader": "^3.4.0",
"@fortawesome/fontawesome-free": "^5.12.1",
"@mdi/font": "^4.9.95",
"@vue/cli-plugin-babel": "^4.2.3",
"@vue/cli-plugin-eslint": "^4.2.3",
"@vue/cli-service": "^4.2.3",
"babel-eslint": "^10.1.0",
"css-loader": "^3.4.2",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.0.0",
"material-design-icons-iconfont": "^5.0.1",
"sass": "^1.19.0",
"sass-loader": "^8.0.0",
"sass": "^1.26.3",
"sass-loader": "^8.0.2",
"vue-cli-plugin-route": "0.0.7",
"vue-cli-plugin-vuetify": "^1.1.0",
"vue-router": "^3.1.3",
"vue-template-compiler": "^2.6.10",
"vuetify-loader": "^1.3.0"
"vue-cli-plugin-vuetify": "^1.1.2",
"vue-router": "^3.1.6",
"vue-template-compiler": "^2.6.11",
"vuetify-loader": "^1.4.3"
},
"eslintConfig": {
"root": true,
Expand Down
2 changes: 1 addition & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<link rel="icon" href="<%= BASE_URL %>favicon.ico" id="favicon" />
<title>KlipperWebControl</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css">
Expand Down
61 changes: 60 additions & 1 deletion src/App.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<template>
<v-app>
<vue-headful
:title="getTitle"
/>
<v-navigation-drawer
class="sidebar-wrapper" persistent v-model="drawer" enable-resize-watcher fixed app
:src="require('./assets/bg-navi.jpg')"
Expand Down Expand Up @@ -64,7 +67,7 @@

<script>
import routes from './routes';
import { mapState } from 'vuex';
import { mapState, mapGetters } from 'vuex';
export default {
props: {
Expand All @@ -84,6 +87,7 @@ export default {
this.$socket.sendObj('get_printer_info', {}, 'getKlipperInfo');
this.$socket.sendObj('get_printer_objects', {}, 'getObjectInfo');
this.$socket.sendObj('get_printer_status', { heater: [] }, 'getObjectInfo');
this.$socket.sendObj('get_printer_status', { configfile: ['config'] }, 'getPrinterConfig');
this.$socket.sendObj('post_printer_subscriptions', {
gcode: [],
toolhead: [],
Expand All @@ -110,13 +114,68 @@ export default {
loadingEmergencyStop: state => state.socket.loadingEmergencyStop,
isConnected: state => state.socket.isConnected,
isConnecting: state => !state.socket.isConnected,
progress: state => state.printer.virtual_sdcard.progress,
}),
...mapGetters([
'getTitle'
])
},
methods: {
emergencyStop: function() {
this.$store.commit('setLoadingEmergencyStop', true);
this.$socket.sendObj('post_printer_gcode', {script: 'M112'}, 'setLoadingEmergencyStop');
},
drawFavicon(val) {
let favicon = document.getElementById('favicon');
if (val === 0) favicon.href = "/favicon.ico";
else {
let faviconSize = 64;
let canvas = document.createElement('canvas');
canvas.width = faviconSize;
canvas.height = faviconSize;
let context = canvas.getContext('2d');
let centerX = canvas.width / 2;
let centerY = canvas.height / 2;
let radius = 32;
let percent = val * 100;
/* draw the grey circle */
context.beginPath();
context.moveTo(centerX, centerY);
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
context.closePath();
context.fillStyle = "#ddd";
context.fill();
context.strokeStyle = "rgba(200, 208, 218, 0.66)";
context.stroke();
/* draw the green circle based on percentage */
let startAngle = 1.5 * Math.PI;
let endAngle = 0;
let unitValue = (Math.PI - 0.5 * Math.PI) / 25;
if (percent >= 0 && percent <= 25) endAngle = startAngle + (percent * unitValue);
else if (percent > 25 && percent <= 50) endAngle = startAngle + (percent * unitValue);
else if (percent > 50 && percent <= 75) endAngle = startAngle + (percent * unitValue);
else if (percent > 75 && percent <= 100) endAngle = startAngle + (percent * unitValue);
context.beginPath();
context.moveTo(centerX, centerY);
context.arc(centerX, centerY, radius, startAngle, endAngle, false);
context.closePath();
context.fillStyle = "#e41313";
context.fill();
favicon.href = canvas.toDataURL('image/png');
}
}
},
watch: {
progress: {
handler: function(val) {
this.drawFavicon(val);
}
}
}
}
</script>
Expand Down
11 changes: 11 additions & 0 deletions src/charts/LineChart.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ export default {
fontFamily: 'Roboto,sans-serif'
}
},
tooltips: {
enabled: true,
callbacks: {
title: function (tooltipItem, data) {
return data['labels'][tooltipItem[0]['index']];
},
label: function (tooltipItem, data) {
return data['datasets'][0]['data'][tooltipItem['index']];
},
}
},
maintainAspectRatio: false,
responsive: true,
responsiveAnimationDuration: 0, // animation duration after a resize
Expand Down
25 changes: 20 additions & 5 deletions src/components/panels/ControlPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<v-btn @click="doSend('X-100')" cols="1" class="flex-grow-1 flex-shrink-0"><v-icon left>mdi-chevron-left</v-icon><span>X-100</span></v-btn>
<v-btn @click="doSend('X-10')" cols="1" class="flex-grow-1 flex-shrink-0"><v-icon left>mdi-chevron-left</v-icon><span>X-10</span></v-btn>
<v-btn @click="doSend('X-1')" cols="1" class="flex-grow-1 flex-shrink-0"><v-icon left>mdi-chevron-left</v-icon><span>X-1</span></v-btn>
<v-btn @click="doHomeX" :color="homedAxes.includes('x') ? 'primary' : 'warning'" :loading="loadingHomeX"><span>Home X</span></v-btn>
<v-btn @click="doHomeX" :color="homedAxes.includes('x') ? 'primary' : 'warning'" :loading="loadingHomeX"><v-icon class="mdi mdi-home"></v-icon></v-btn>
<v-btn @click="doSend('X+1')" cols="1" class="flex-grow-1 flex-shrink-0"><span>X+1</span><v-icon right>mdi-chevron-right</v-icon></v-btn>
<v-btn @click="doSend('X+10')" cols="1" class="flex-grow-1 flex-shrink-0"><span>X+10</span><v-icon right>mdi-chevron-right</v-icon></v-btn>
<v-btn @click="doSend('X+100')" cols="1" class="flex-grow-1 flex-shrink-0"><span>X+100</span><v-icon right>mdi-chevron-right</v-icon></v-btn>
Expand All @@ -21,7 +21,7 @@
<v-btn @click="doSend('Y-100')" cols="1" class="flex-grow-1 flex-shrink-0"><v-icon left>mdi-chevron-left</v-icon><span>Y-100</span></v-btn>
<v-btn @click="doSend('Y-10')" cols="1" class="flex-grow-1 flex-shrink-0"><v-icon left>mdi-chevron-left</v-icon><span>Y-10</span></v-btn>
<v-btn @click="doSend('Y-1')" cols="1" class="flex-grow-1 flex-shrink-0"><v-icon left>mdi-chevron-left</v-icon><span>Y-1</span></v-btn>
<v-btn @click="doHomeY" :color="homedAxes.includes('y') ? 'primary' : 'warning'" :loading="loadingHomeY"><span>Home Y</span></v-btn>
<v-btn @click="doHomeY" :color="homedAxes.includes('y') ? 'primary' : 'warning'" :loading="loadingHomeY"><v-icon class="mdi mdi-home"></v-icon></v-btn>
<v-btn @click="doSend('Y+1')" cols="1" class="flex-grow-1 flex-shrink-0"><span>Y+1</span><v-icon right>mdi-chevron-right</v-icon></v-btn>
<v-btn @click="doSend('Y+10')" cols="1" class="flex-grow-1 flex-shrink-0"><span>Y+10</span><v-icon right>mdi-chevron-right</v-icon></v-btn>
<v-btn @click="doSend('Y+100')" cols="1" class="flex-grow-1 flex-shrink-0"><span>Y+100</span><v-icon right>mdi-chevron-right</v-icon></v-btn>
Expand All @@ -32,15 +32,17 @@
<v-btn @click="doSend('Z-25')" cols="1" class="flex-grow-1 flex-shrink-0"><v-icon left>mdi-chevron-left</v-icon><span>Z-25</span></v-btn>
<v-btn @click="doSend('Z-1')" cols="1" class="flex-grow-1 flex-shrink-0"><v-icon left>mdi-chevron-left</v-icon><span>Z-1</span></v-btn>
<v-btn @click="doSend('Z-0.1')" cols="1" class="flex-grow-1 flex-shrink-0"><v-icon left>mdi-chevron-left</v-icon><span>Z-0.1</span></v-btn>
<v-btn @click="doHomeZ" :color="homedAxes.includes('z') ? 'primary' : 'warning'" :loading="loadingHomeZ"><span>Home Z</span></v-btn>
<v-btn @click="doHomeZ" :color="homedAxes.includes('z') ? 'primary' : 'warning'" :loading="loadingHomeZ"><v-icon class="mdi mdi-home"></v-icon></v-btn>
<v-btn @click="doSend('Z+0.1')" cols="1" class="flex-grow-1 flex-shrink-0"><span>Z+0.1</span><v-icon right>mdi-chevron-right</v-icon></v-btn>
<v-btn @click="doSend('Z+1')" cols="1" class="flex-grow-1 flex-shrink-0"><span>Z+1</span><v-icon right>mdi-chevron-right</v-icon></v-btn>
<v-btn @click="doSend('Z+25')" cols="1" class="flex-grow-1 flex-shrink-0"><span>Z+25</span><v-icon right>mdi-chevron-right</v-icon></v-btn>
</v-btn-toggle>
</v-row>
<v-row class="px-3 mt-3">
<v-spacer></v-spacer>
<v-btn @click="doRestart" :loading="loadingRestart" color="error"><v-icon left>mdi-cached</v-icon>Restart</v-btn>
<v-btn @click="doHome" :loading="loadingHome" :color="homedAxes.includes('xyz') ? 'primary' : 'warning'"><v-icon left>mdi-home</v-icon>Home all</v-btn>
<v-btn v-if="config.hasOwnProperty('quad_gantry_level')" @click="doQGL" :loading="loadingQGL" color="primary" class="ml-3">QGL</v-btn>
<v-btn @click="doRestart" :loading="loadingRestart" color="error" class="ml-3"><v-icon left>mdi-cached</v-icon>Restart</v-btn>
<v-btn @click="doRestartFirmware" :loading="loadingRestartFirmware" color="error" class="ml-3"><v-icon left>mdi-cached</v-icon>Firmware Restart</v-btn>
</v-row>
</v-col>
Expand All @@ -61,22 +63,31 @@
},
computed: {
...mapState({
loadingHome: state => state.socket.loadingHome,
loadingHomeX: state => state.socket.loadingHomeX,
loadingHomeY: state => state.socket.loadingHomeY,
loadingHomeZ: state => state.socket.loadingHomeZ,
loadingQGL: state => state.socket.loadingQGL,
loadingRestart: state => state.socket.loadingRestart,
loadingRestartFirmware: state => state.socket.loadingRestartFirmware,
homedAxes: state => state.printer.toolhead.homed_axes,
config: state => state.config,
}),
...mapMutations([
'setLoadingHome',
'setLoadingHomeX',
'setLoadingHomeY',
'setLoadingHomeZ',
'setLoadingQGL',
'setLoadingRestart',
'setLoadingRestartFirmware',
])
]),
},
methods: {
doHome() {
this.$store.commit('setLoadingHome', true);
this.$socket.sendObj('post_printer_gcode', { script: "G28" }, "responseHome");
},
doHomeX() {
this.$store.commit('setLoadingHomeX', true);
this.$socket.sendObj('post_printer_gcode', { script: "G28 X" }, "responseHomeX");
Expand All @@ -89,6 +100,10 @@
this.$store.commit('setLoadingHomeZ', true);
this.$socket.sendObj('post_printer_gcode', { script: "G28 Z" }, "responseHomeZ");
},
doQGL() {
this.$store.commit('setLoadingQGL', true);
this.$socket.sendObj('post_printer_gcode', { script: "quad_gantry_level" }, "responseQGL");
},
doSend(gcode) {
gcode = "G91" + "\n" +
"G1 " + gcode + " F6000" + "\n" +
Expand Down
45 changes: 45 additions & 0 deletions src/components/panels/MacrosPanel.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<template>
<v-card>
<v-list-item>
<v-list-item-avatar color="grey"><v-icon dark>fa-thermometer-three-quarters</v-icon></v-list-item-avatar>
<v-list-item-content>
<v-list-item-title class="headline">Macros</v-list-item-title>
<v-list-item-subtitle>
{{ getMacros.length }} Macros
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-divider class="my-2"></v-divider>
<v-card-text class="px-0 pt-0 pb-2 content text-center">
<div v-for="(macro, index) in getMacros" v-bind:key="index+99" style="display: inline-block;" class="mx-1 my-1">
<v-btn color="primary" class="ml-3" @click="doSend(macro.name)">{{ macro.name }}</v-btn>
</div>
</v-card-text>
</v-card>
</template>

<script>
import {mapGetters} from 'vuex'
export default {
components: {
},
data: function() {
return {
}
},
computed: {
...mapGetters([
'getMacros',
]),
},
methods: {
doSend(gcode) {
this.$socket.sendObj('post_printer_gcode', { script: gcode }, "sendGcode");
},
},
}
</script>
Loading

0 comments on commit 54aaf8d

Please sign in to comment.