feature: add webcam support to printer farm

Signed-off-by: Stefan Dej <meteyou@gmail.com>
This commit is contained in:
Stefan Dej 2021-04-04 03:02:58 +02:00
parent 88afe071e1
commit c17951b53d
5 changed files with 88 additions and 33 deletions

View File

@ -3,6 +3,22 @@
opacity: 0.6;
filter: grayscale(70%);
}
.webcamContainer,
.webcamContainer .vue-load-image,
.webcamContainer>div,
.webcamContainer img {
position: absolute !important;
top: 0; left: 0; right: 0; bottom: 0;
}
.webcamContainer img {
height: 100%;
}
.webcamContainer .webcamFpsOutput {
display: none;
}
</style>
<template>
@ -15,12 +31,49 @@
<v-toolbar-title>
<span class="subheading"><v-icon left>mdi-printer-3d</v-icon>{{ printer_name }}</span>
</v-toolbar-title>
<v-spacer></v-spacer>
<v-item-group v-if="this.printer_webcams.length">
<v-menu :offset-y="true" title="Webcam">
<template v-slot:activator="{ on, attrs }">
<v-btn small class="px-2 minwidth-0" color="grey darken-3" v-bind="attrs" v-on="on">
<v-icon small>mdi-webcam</v-icon>
<v-icon small>mdi-menu-down</v-icon>
</v-btn>
</template>
<v-list dense class="py-0">
<v-list-item link @click="currentCamName = 'off'">
<v-list-item-icon class="mr-0">
<v-icon small>mdi-webcam-off</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>{{ $t('Panels.FarmPrinterPanel.WebcamOff') }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-list-item v-for="webcam of this.printer_webcams" v-bind:key="webcam.index" link @click="currentCamName = webcam.name">
<v-list-item-icon class="mr-0">
<v-icon small>{{ webcam.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title v-text="webcam.name"></v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-menu>
</v-item-group>
</v-toolbar>
<v-img
height="200px"
:src="printer_image"
class="d-flex align-end"
>
<div v-if="currentCamName !== 'off' && currentWebcam" class="webcamContainer">
<template v-if="'service' in currentWebcam && currentWebcam.service === 'mjpegstreamer'">
<webcam-mjpegstreamer :cam-settings="currentWebcam"></webcam-mjpegstreamer>
</template>
<template v-if="'service' in currentWebcam && currentWebcam.service === 'mjpegstreamer-adaptive'">
<webcam-mjpegstreamer-adaptive :cam-settings="currentWebcam"></webcam-mjpegstreamer-adaptive>
</template>
</div>
<v-card-title class="white--text py-2" style="background-color: rgba(0,0,0,0.3); backdrop-filter: blur(3px);">
<v-row>
<v-col class="col-auto pr-0 d-flex align-center" style="width: 58px">
@ -48,10 +101,18 @@
<script>
import { mapState } from 'vuex'
import Mjpegstreamer from "@/components/webcams/Mjpegstreamer"
import MjpegstreamerAdaptive from "@/components/webcams/MjpegstreamerAdaptive"
export default {
components: {
"webcam-mjpegstreamer": Mjpegstreamer,
"webcam-mjpegstreamer-adaptive": MjpegstreamerAdaptive,
},
data: function() {
return {
currentCamName: "off",
}
},
props: {
printer: {
@ -102,6 +163,19 @@
get() {
return this.$store.getters["farm/"+this.printer._namespace+"/getPrinterPreview"]
}
},
printer_webcams: {
get() {
return this.$store.getters["farm/"+this.printer._namespace+"/getPrinterWebcams"]
}
},
currentWebcam: {
get() {
const currentCam = this.printer_webcams.find(webcam => webcam.name === this.currentCamName)
if (currentCam) return currentCam
return false
}
}
},
methods: {

View File

@ -190,7 +190,9 @@ export default {
Extrude: "Extrude",
Macros: "Macros"
},
FarmPrinterPanel: {},
FarmPrinterPanel: {
WebcamOff: "Off",
},
KlippyStatePanel: {
KlippyState: "Klippy-State: ",
KlippyInfo: "Moonraker can't connect to Klippy!\nPlease check if the Klipper service is running and an UDS (Unix Domain Socket) is configured.",

View File

@ -46,10 +46,6 @@ export default {
commit("setData", data.params[0])
break
case "notify_filelist_changed":
commit("notifyFilelistChanged", data.params[0])
break
case "notify_klippy_disconnected":
dispatch("disconnectKlippy")
break

View File

@ -76,20 +76,6 @@ export default {
},
getImage: state => {
/*if (
'gui' in state.data &&
'webcam' in state.data.gui &&
'url' in state.data.gui.webcam &&
state.data.gui.webcam.url !== "" &&
'bool' in state.data.gui.webcam &&
state.data.gui.webcam.bool &&
'dashbaord' in state.data.gui &&
'boolWebcam' in state.data.gui.dashboard &&
state.data.gui.dashboard.boolWebcam
) {
return state.data.gui.webcam.url
} else*/
if (
state.current_file &&
"filename" in state.current_file &&
@ -256,4 +242,14 @@ export default {
return 0
},
getPrinterWebcams: (state) => {
if (
'gui' in state.data &&
'webcam' in state.data.gui &&
'configs' in state.data.gui.webcam
) return state.data.gui.webcam.configs
return []
}
}

View File

@ -64,19 +64,6 @@ export default {
}
},
notifyFilelistChanged( state, payload) {
if (
payload.action === "upload_file" &&
payload.item.root === "config" &&
payload.item.path === ".mainsail.json"
) {
fetch('//'+state.socket.hostname+':'+state.socket.port+'/server/files/config/.mainsail.json?time='+Date.now())
.then(res => res.json()).then(file => {
this.commit("farm/"+state._namespace+"/setMainsailJson", file)
})
}
},
setDatabases(state, payload) {
Vue.set(state, 'databases', payload.namespaces)
},