feat: temperature panel rework (#748)

Co-authored-by: Stefan Dej <meteyou@gmail.com>
This commit is contained in:
th33xitus 2022-04-24 23:26:45 +02:00 committed by GitHub
parent 1ea5edd504
commit aee5efcd3d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 694 additions and 623 deletions

View File

@ -89,7 +89,7 @@ export default class TempChart extends Mixins(BaseMixin) {
}, },
yAxis: [ yAxis: [
{ {
name: this.$t('Panels.ToolsPanel.TemperaturesInChart'), name: this.$t('Panels.TemperaturePanel.TemperaturesInChart'),
type: 'value', type: 'value',
min: 0, min: 0,
max: (value: any) => { max: (value: any) => {

View File

@ -0,0 +1,125 @@
<style scoped>
._temp-input {
font-size: 0.875rem;
min-width: 4rem;
max-width: 5rem;
}
._temp-input >>> .v-input__slot {
min-height: 1rem !important;
padding-left: 8px !important;
padding-right: 8px !important;
}
._temp-input >>> .v-text-field__slot input {
padding: 4px 0 4px;
}
._preset {
font-size: 0.8125rem;
font-weight: 500;
}
</style>
<template>
<div class="d-flex align-center">
<v-text-field
v-model="value"
suffix="°C"
type="number"
dense
outlined
hide-details
hide-spin-buttons
class="_temp-input pr-1"
@blur="value = target"
@focus="$event.target.select()"
@keyup.enter="setTemps"></v-text-field>
<v-menu v-if="presets" :offset-y="true" left title="Preheat">
<template #activator="{ on, attrs }">
<v-btn
:disabled="['printing', 'paused'].includes(printer_state)"
tabindex="-1"
x-small
plain
v-bind="attrs"
class="pa-0"
style="min-width: 24px"
v-on="on">
<v-icon>{{ mdiMenuDown }}</v-icon>
</v-btn>
</template>
<v-list dense class="py-0">
<v-list-item
v-for="preset of presets"
:key="preset.index"
link
style="min-height: 32px"
@click="doSend(`${command} ${attributeName}=${name} TARGET=${preset.value}`)">
<div class="d-flex align-center _preset">
<v-icon v-if="preset.value === 0" else color="primary" small class="mr-1">
{{ mdiSnowflake }}
</v-icon>
<v-icon v-else small class="mr-1">{{ mdiFire }}</v-icon>
<span style="padding-top: 2px">{{ preset.value }}°C</span>
</div>
</v-list-item>
</v-list>
</v-menu>
</div>
</template>
<script lang="ts">
import Component from 'vue-class-component'
import { Mixins, Prop, Watch } from 'vue-property-decorator'
import BaseMixin from '@/components/mixins/base'
import ControlMixin from '@/components/mixins/control'
import { mdiSnowflake, mdiFire, mdiMenuDown } from '@mdi/js'
@Component
export default class TemperatureInput extends Mixins(BaseMixin, ControlMixin) {
mdiSnowflake = mdiSnowflake
mdiFire = mdiFire
mdiMenuDown = mdiMenuDown
private value: any = 0
@Prop({ type: String, required: true }) declare readonly name: string
@Prop({ type: Number, required: true, default: 0 }) declare readonly target: number
@Prop({ type: Number, required: true }) declare readonly min_temp: number
@Prop({ type: Number, required: true }) declare readonly max_temp: number
@Prop({ type: String, required: true }) declare readonly command: string
@Prop({ type: String, required: true }) declare readonly attributeName: string
@Prop({ type: Array, default: [] }) declare presets: number[]
setTemps(): void {
if (typeof this.value === 'object') this.value = this.value.value ?? 0
if (this.value === null) this.value = 0
if (this.value > this.max_temp) {
this.value = { value: this.target, text: this.target }
this.$toast.error(
this.$t('Panels.TemperaturePanel.TempTooHigh', { name: this.name, max: this.max_temp }) + ''
)
} else if (this.value < this.min_temp && this.value != 0) {
this.value = { value: this.target, text: this.target }
this.$toast.error(
this.$t('Panels.TemperaturePanel.TempTooLow', { name: this.name, min: this.min_temp }) + ''
)
} else if (this.target !== parseFloat(this.value)) {
const gcode = this.command + ' ' + this.attributeName + '=' + this.name + ' TARGET=' + this.value
this.$store.dispatch('server/addEvent', { message: gcode, type: 'command' })
this.$socket.emit('printer.gcode.script', { script: gcode })
}
}
mounted() {
this.value = this.target
}
@Watch('target')
targetChanged(newVal: number): void {
this.value = newVal
}
}
</script>

View File

@ -1,96 +0,0 @@
<style scoped>
.tool-input {
min-width: 5rem;
margin-top: 0;
padding: 0;
}
.tool-input .v-input__slot {
margin-bottom: 0;
}
.tool-input .v-text-field__details {
display: none;
}
.tool-input input {
-moz-appearance: textfield;
}
.tool-input input::-webkit-outer-spin-button,
.tool-input input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
</style>
<template>
<v-combobox
v-model="value"
dense
hide-details
:items="items"
item-text="value"
type="number"
hide-spin-buttons
@keyup.enter="setTemps"
@keydown.tab="setTemps"
@change="changeValue"
@blur="onBlur"></v-combobox>
</template>
<script lang="ts">
import Component from 'vue-class-component'
import { Mixins, Prop, Watch } from 'vue-property-decorator'
import BaseMixin from '@/components/mixins/base'
@Component
export default class ToolInput extends Mixins(BaseMixin) {
private value: any = 0
@Prop({ type: String, required: true }) declare readonly name: string
@Prop({ type: Number, required: true, default: 0 }) declare readonly target: number
@Prop({ type: Number, required: true }) declare readonly min_temp: number
@Prop({ type: Number, required: true }) declare readonly max_temp: number
@Prop({ type: String, required: true }) declare readonly command: string
@Prop({ type: String, required: true }) declare readonly attributeName: string
@Prop({ type: Array, default: [] }) declare items: number[]
changeValue(newVal: any) {
if (typeof newVal === 'object') {
this.setTemps()
}
}
onBlur(event: any) {
if ('target' in event && event.target && 'value' in event.target) {
this.value = event.target.value ?? this.value
this.setTemps()
}
}
setTemps(): void {
if (typeof this.value === 'object') this.value = this.value.value ?? 0
if (this.value === null) this.value = 0
if (this.value > this.max_temp) {
this.value = { value: this.target, text: this.target }
this.$toast.error(this.$t('Panels.ToolsPanel.TempTooHigh', { name: this.name, max: this.max_temp }) + '')
} else if (this.value < this.min_temp && this.value != 0) {
this.value = { value: this.target, text: this.target }
this.$toast.error(this.$t('Panels.ToolsPanel.TempTooLow', { name: this.name, min: this.min_temp }) + '')
} else if (this.target !== parseFloat(this.value)) {
const gcode = this.command + ' ' + this.attributeName + '=' + this.name + ' TARGET=' + this.value
this.$store.dispatch('server/addEvent', { message: gcode, type: 'command' })
this.$socket.emit('printer.gcode.script', { script: gcode })
}
}
mounted() {
this.value = this.target
}
@Watch('target')
targetChanged(newVal: number): void {
this.value = newVal
}
}
</script>

View File

@ -0,0 +1,425 @@
<template>
<div>
<panel
v-if="klipperReadyForGui"
:icon="mdiThermometerLines"
:title="$t('Panels.TemperaturePanel.Headline').toString()"
:collapsible="true"
card-class="temperature-panel">
<!-- PRESET MENU -->
<template #buttons>
<v-menu v-if="presets.length" :offset-y="true" left title="Preheat">
<template #activator="{ on, attrs }">
<v-btn
text
tile
color="primary"
v-bind="attrs"
:disabled="['printing', 'paused'].includes(printer_state)"
class="pa-1"
v-on="on">
<span class="d-none ml-1 d-md-block">{{ $t('Panels.TemperaturePanel.Presets') }}</span>
<v-icon class="d-md-none">{{ mdiFire }}</v-icon>
<v-icon>{{ mdiMenuDown }}</v-icon>
</v-btn>
</template>
<v-list dense class="py-0">
<v-list-item v-for="preset of presets" :key="preset.index" link @click="preheat(preset)">
<div class="d-flex align-center _preset-title">
<v-icon small class="mr-1">{{ mdiFire }}</v-icon>
<span style="padding-top: 2px">{{ preset.name }}</span>
</div>
</v-list-item>
</v-list>
<v-divider></v-divider>
<v-list dense class="py-0">
<v-list-item link @click="cooldown()">
<div class="d-flex align-center _preset-title">
<v-icon small color="primary" class="mr-1">{{ mdiSnowflake }}</v-icon>
<span class="primary--text">{{ $t('Panels.TemperaturePanel.Cooldown') }}</span>
</div>
</v-list-item>
</v-list>
</v-menu>
<v-btn
v-if="presets.length === 0"
:icon="$vuetify.breakpoint.smAndDown"
:text="$vuetify.breakpoint.mdAndUp"
tile
color="primary"
@click="cooldown()">
<v-icon small>{{ mdiSnowflake }}</v-icon>
<span class="d-none ml-1 d-md-inline">{{ $t('Panels.TemperaturePanel.Cooldown') }}</span>
</v-btn>
<v-menu
:offset-y="true"
:close-on-content-click="false"
:title="$t('Panels.TemperaturePanel.SetupTemperatures')">
<template #activator="{ on, attrs }">
<v-btn icon tile v-bind="attrs" v-on="on">
<v-icon small>{{ mdiCog }}</v-icon>
</v-btn>
</template>
<v-list>
<v-list-item class="minHeight36">
<v-checkbox
v-model="boolTempchart"
class="mt-0"
hide-details
:label="$t('Panels.TemperaturePanel.ShowChart')"></v-checkbox>
</v-list-item>
<v-list-item class="minHeight36">
<v-checkbox
v-model="autoscaleTempchart"
class="mt-0"
hide-details
:label="$t('Panels.TemperaturePanel.AutoscaleChart')"></v-checkbox>
</v-list-item>
</v-list>
</v-menu>
</template>
<v-card-text class="pa-0">
<responsive
:breakpoints="{
mobile: (el) => el.width <= 390,
}">
<template #default="{ el }">
<v-simple-table class="temperature-panel-table">
<thead>
<tr>
<th class="icon">&nbsp;</th>
<th class="name">{{ $t('Panels.TemperaturePanel.Name') }}</th>
<th v-if="!el.is.mobile" class="state">
{{ $t('Panels.TemperaturePanel.State') }}
</th>
<th class="current">
{{ $t('Panels.TemperaturePanel.Current') }}
</th>
<th class="target">
{{ $t('Panels.TemperaturePanel.Target') }}
</th>
</tr>
</thead>
<tbody>
<tr v-for="(object, index) in temperatureObjects" :key="index">
<td class="icon">
<v-icon
:color="object.iconColor"
:class="`_no-focus-style ${object.iconClass}`"
style="cursor: pointer"
tabindex="-1"
@click="openHeater(object)">
{{ object.icon }}
</v-icon>
</td>
<td class="name">
<span style="cursor: pointer" @click="openHeater(object)">
{{ convertName(object.name) }}
</span>
</td>
<td v-if="!el.is.mobile" class="state">
<v-tooltip v-if="object.state !== null" top>
<template #activator="{ on, attrs }">
<small v-bind="attrs" v-on="on">
{{ object.state }}
</small>
</template>
<span>{{ $t('Panels.TemperaturePanel.Avg') }}: {{ object.avgState }}</span>
</v-tooltip>
</td>
<td class="current">
<v-tooltip
top
:disabled="
!(
object.measured_min_temp !== null ||
object.measured_max_temp !== null
)
">
<template #activator="{ on, attrs }">
<span style="cursor: default" v-bind="attrs" v-on="on">
{{ object.temperature.toFixed(1) }}°C
</span>
</template>
<span>
{{ $t('Panels.TemperaturePanel.Max') }}:
{{ object.measured_max_temp }}°C
<br />
{{ $t('Panels.TemperaturePanel.Min') }}:
{{ object.measured_min_temp }}°C
</span>
</v-tooltip>
<div v-for="(values, key) of object.additionSensors" :key="key">
<span v-if="values.bool" class="d-block">
<small>{{ values.value }} {{ values.unit }}</small>
</span>
</div>
<div v-if="object.rpm !== null">
<small :class="object.rpmClass">{{ object.rpm }}</small>
</div>
</td>
<td class="target">
<temperature-input
v-if="object.command !== null"
:name="object.name"
:target="object.target"
:presets="object.presets"
:min_temp="object.min_temp"
:max_temp="object.max_temp"
:command="object.command"
:attribute-name="object.commandAttributeName"></temperature-input>
</td>
</tr>
</tbody>
</v-simple-table>
</template>
</responsive>
</v-card-text>
<v-card-text v-if="boolTempchart" class="pa-0">
<v-divider class="my-2"></v-divider>
<v-row>
<v-col class="py-0">
<temp-chart></temp-chart>
</v-col>
</v-row>
</v-card-text>
</panel>
<!-- COLOR-PICKER -->
<v-dialog v-model="editHeater.bool" persistent :width="400">
<panel
:title="convertName(editHeater.name)"
:icon="editHeater.icon"
card-class="temperature-edit-heater-dialog"
:margin-bottom="false">
<template #buttons>
<v-btn icon tile @click="editHeater.bool = false">
<v-icon>{{ mdiCloseThick }}</v-icon>
</v-btn>
</template>
<v-card-text class="pt-6">
<v-row v-for="dataset in editHeater.chartSeries" :key="dataset">
<v-col class="col-12 py-1">
<v-checkbox
v-model="editHeater['bool' + dataset.charAt(0).toUpperCase() + dataset.slice(1)]"
:label="
$t('Panels.TemperaturePanel.ShowNameInChart', {
name: $t(
'Panels.TemperaturePanel.Dataset.' +
dataset.charAt(0).toUpperCase() +
dataset.slice(1)
),
})
"
hide-details
class="mt-0"
@change="setVisible(dataset)"></v-checkbox>
</v-col>
</v-row>
<v-row v-for="key in Object.keys(editHeater.additionSensors)" :key="key">
<v-col class="col-12 py-1">
<v-checkbox
v-model="editHeater.additionSensors[key]['bool']"
:label="$t('Panels.TemperaturePanel.ShowNameInList', { name: key })"
hide-details
class="mt-0"
@change="setVisibleAdditionalSensor(key)"></v-checkbox>
</v-col>
</v-row>
<v-row>
<v-col class="col-12 text-center pb-0">
<v-color-picker
hide-mode-switch
mode="hexa"
:value="editHeater.color"
class="mx-auto"
@update:color="setChartColor"></v-color-picker>
</v-col>
</v-row>
</v-card-text>
</panel>
</v-dialog>
</div>
</template>
<script lang="ts">
import Component from 'vue-class-component'
import { Mixins } from 'vue-property-decorator'
import { convertName } from '@/plugins/helpers'
import { Debounce } from 'vue-debounce-decorator'
import { GuiPresetsStatePreset } from '@/store/gui/presets/types'
import { PrinterStateTemperatureObject } from '@/store/printer/types'
import BaseMixin from '@/components/mixins/base'
import ControlMixin from '@/components/mixins/control'
import TempChart from '@/components/charts/TempChart.vue'
import TemperatureInput from '@/components/inputs/TemperatureInput.vue'
import Panel from '@/components/ui/Panel.vue'
import Responsive from '@/components/ui/Responsive.vue'
import { datasetTypes } from '@/store/variables'
import { mdiCloseThick, mdiCog, mdiFan, mdiSnowflake, mdiFire, mdiMenuDown, mdiThermometerLines } from '@mdi/js'
@Component({
components: { Panel, TempChart, TemperatureInput, Responsive },
})
export default class TemperaturePanel extends Mixins(BaseMixin, ControlMixin) {
mdiFan = mdiFan
mdiSnowflake = mdiSnowflake
mdiCloseThick = mdiCloseThick
mdiCog = mdiCog
mdiFire = mdiFire
mdiMenuDown = mdiMenuDown
mdiThermometerLines = mdiThermometerLines
convertName = convertName
datasetTypes = datasetTypes
private editHeater: any = {
bool: false,
name: '',
icon: '',
boolTemperature: false,
boolTarget: false,
boolPower: false,
boolSpeed: false,
additionSensors: {},
color: '',
}
get presets(): GuiPresetsStatePreset[] {
return this.$store.getters['gui/presets/getPresets'] ?? []
}
get cooldownGcode(): string {
return this.$store.getters['gui/presets/getCooldownGcode']
}
get boolTempchart(): boolean {
return this.$store.state.gui.view.tempchart.boolTempchart ?? false
}
set boolTempchart(newVal: boolean) {
this.$store.dispatch('gui/saveSetting', { name: 'view.tempchart.boolTempchart', value: newVal })
}
get autoscaleTempchart(): boolean {
return this.$store.state.gui.view.tempchart.autoscale ?? false
}
set autoscaleTempchart(newVal: boolean) {
this.$store.dispatch('gui/saveSetting', { name: 'view.tempchart.autoscale', value: newVal })
}
get temperatureObjects() {
return this.$store.getters['printer/getTemperatureObjects'] ?? []
}
preheat(preset: GuiPresetsStatePreset): void {
for (const [name, attributes] of Object.entries(preset.values)) {
if (attributes.bool) {
let gcode = `SET_HEATER_TEMPERATURE HEATER=${name} TARGET=${attributes.value}`
if (attributes.type === 'temperature_fan') {
const fanName = name.replace('temperature_fan ', '')
gcode = `SET_TEMPERATURE_FAN_TARGET temperature_fan=${fanName} TARGET=${attributes.value}`
}
this.$store.dispatch('server/addEvent', { message: gcode, type: 'command' })
this.$socket.emit('printer.gcode.script', { script: gcode })
}
}
if (preset.gcode !== '') {
setTimeout(() => {
this.$store.dispatch('server/addEvent', { message: preset.gcode, type: 'command' })
this.$socket.emit('printer.gcode.script', { script: preset.gcode })
}, 100)
}
}
cooldown(): void {
this.$store.dispatch('server/addEvent', { message: this.cooldownGcode, type: 'command' })
this.$socket.emit('printer.gcode.script', { script: this.cooldownGcode })
}
openHeater(object: PrinterStateTemperatureObject): void {
this.editHeater.name = object.name
this.editHeater.icon = object.icon
this.editHeater.color = object.chartColor
this.editHeater.chartSeries = 'chartSeries' in object ? object.chartSeries : []
this.editHeater.boolTemperature = this.$store.getters['gui/getDatasetValue']({
name: object.name,
type: 'temperature',
})
this.editHeater.boolTarget = this.$store.getters['gui/getDatasetValue']({ name: object.name, type: 'target' })
this.editHeater.boolPower = this.$store.getters['gui/getDatasetValue']({ name: object.name, type: 'power' })
this.editHeater.boolSpeed = this.$store.getters['gui/getDatasetValue']({ name: object.name, type: 'speed' })
this.editHeater.additionSensors = object.additionSensors
this.editHeater.bool = true
}
setVisible(type: string): void {
const serieName = 'bool' + type.charAt(0).toUpperCase() + type.slice(1)
const value = this.editHeater[serieName]
const name = 'view.tempchart.datasetSettings.' + this.editHeater.name + '.' + type
this.$store.dispatch('gui/saveSetting', { name, value })
}
setVisibleAdditionalSensor(sensor: string): void {
const name = 'view.tempchart.datasetSettings.' + this.editHeater.name + '.additionalSensors.' + sensor
this.$store.dispatch('gui/saveSetting', { name, value: this.editHeater.additionSensors[sensor].bool })
}
@Debounce(500)
setChartColor(value: string | any): void {
if (typeof value === 'object' && 'hex' in value) value = value.hex
this.$store.commit('printer/tempHistory/setColor', { name: this.editHeater.name, value: value })
const name = 'view.tempchart.datasetSettings.' + this.editHeater.name + '.color'
this.$store.dispatch('gui/saveSetting', { name, value })
}
}
</script>
<style scoped>
.canvasjs-chart-tooltip > div {
border-radius: 10px !important;
}
._preset-title {
font-size: 0.8125rem;
font-weight: 500;
}
.v-icon._no-focus-style:focus::after {
opacity: 0 !important;
}
.temperature-panel-table th,
.temperature-panel-table td {
padding-top: 5px !important;
padding-bottom: 5px !important;
height: auto !important;
}
.temperature-panel-table .icon {
width: 24px;
padding-right: 0 !important;
text-align: center;
}
.temperature-panel-table .state {
width: 100px;
text-align: right !important;
}
.temperature-panel-table .current {
width: 100px;
text-align: right !important;
}
.temperature-panel-table .target {
width: 140px;
}
</style>

View File

@ -1,501 +0,0 @@
<style scoped>
.heater-row .vertical_align_center {
margin: auto 0;
}
.colHeaterIcons {
width: 68px;
}
.canvasjs-chart-tooltip > div {
border-radius: 10px !important;
}
.datasetColorSymbol {
width: 8px;
height: 8px;
border-style: solid;
border-width: 0px;
cursor: pointer;
border-radius: 50%;
}
</style>
<template>
<panel
v-if="klipperReadyForGui"
:icon="mdiThermometerLines"
:title="$t('Panels.ToolsPanel.Headline')"
:collapsible="true"
card-class="tools-panel">
<template #buttons>
<v-menu v-if="presets.length" :offset-y="true" title="Preheat">
<template #activator="{ on, attrs }">
<v-btn
text
tile
color="primary"
v-bind="attrs"
:disabled="['printing', 'paused'].includes(printer_state)"
class="pa-1"
v-on="on">
<span class="d-none ml-1 d-md-block">{{ $t('Panels.ToolsPanel.Presets') }}</span>
<v-icon class="d-md-none">{{ mdiFire }}</v-icon>
<v-icon>{{ mdiMenuDown }}</v-icon>
</v-btn>
</template>
<v-list dense class="py-0">
<v-list-item v-for="preset of presets" :key="preset.index" link @click="preheat(preset)">
<v-list-item-icon class="mr-0">
<v-icon small>{{ mdiFire }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title v-text="preset.name"></v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
<v-divider></v-divider>
<v-list dense class="py-0">
<v-list-item link @click="cooldown()">
<v-list-item-icon class="mr-0">
<v-icon small color="primary">{{ mdiSnowflake }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title class="primary--text">
{{ $t('Panels.ToolsPanel.Cooldown') }}
</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-menu>
<v-btn
v-if="presets.length === 0"
:icon="$vuetify.breakpoint.smAndDown"
:text="$vuetify.breakpoint.mdAndUp"
tile
color="primary"
@click="cooldown()">
<v-icon small>{{ mdiSnowflake }}</v-icon>
<span class="d-none ml-1 d-md-inline">{{ $t('Panels.ToolsPanel.Cooldown') }}</span>
</v-btn>
<v-menu :offset-y="true" :close-on-content-click="false" :title="$t('Panels.ToolsPanel.SetupTemperatures')">
<template #activator="{ on, attrs }">
<v-btn icon tile v-bind="attrs" v-on="on">
<v-icon small>{{ mdiCog }}</v-icon>
</v-btn>
</template>
<v-list>
<v-list-item class="minHeight36">
<v-checkbox
v-model="boolTempchart"
class="mt-0"
hide-details
:label="$t('Panels.ToolsPanel.ShowChart')"></v-checkbox>
</v-list-item>
<v-list-item class="minHeight36">
<v-checkbox
v-model="autoscaleTempchart"
class="mt-0"
hide-details
:label="$t('Panels.ToolsPanel.AutoscaleChart')"></v-checkbox>
</v-list-item>
</v-list>
</v-menu>
</template>
<v-card-text class="pa-0 content">
<v-container class="px-0">
<v-row align="center">
<v-col class="py-2 font-weight-bold" style="padding-left: 68px">
{{ $t('Panels.ToolsPanel.Name') }}
</v-col>
<v-col
v-if="boolTempchart"
class="py-2 text-center flex-grow-0 font-weight-bold d-none d-md-block"
style="min-width: 75px">
{{ $t('Panels.ToolsPanel.Color') }}
</v-col>
<v-col class="py-2 text-center font-weight-bold d-none d-md-block">
{{ $t('Panels.ToolsPanel.State') }}
</v-col>
<v-col class="py-2 text-center font-weight-bold">{{ $t('Panels.ToolsPanel.Current') }}</v-col>
<v-col class="py-2 pr-8 text-center font-weight-bold">{{ $t('Panels.ToolsPanel.Target') }}</v-col>
</v-row>
<div v-for="(heater, index) in heaters" :key="index">
<v-divider class="my-2"></v-divider>
<v-row align="center">
<v-col class="pl-8 pr-0 flex-grow-0 py-2 colHeaterIcons">
<v-icon :color="heater.iconColor">{{ heater.icon }}</v-icon>
</v-col>
<v-col class="py-2 font-weight-bold">
<span style="cursor: pointer" @click="openHeater(heater)">
{{ convertName(heater.name) }}
</span>
</v-col>
<v-col
v-if="boolTempchart"
class="py-2 flex-grow-0 text-center d-none d-md-block"
style="min-width: 75px">
<div
:style="'background-color: ' + heater.chartColor + 'cc;'"
class="datasetColorSymbol d-inline-block"
@click="openHeater(heater)"></div>
</v-col>
<v-col class="py-2 text-center d-none d-md-block">
<v-tooltip top>
<template #activator="{ on, attrs }">
<small v-bind="attrs" v-on="on">
{{ heater.target > 0 ? heater.power + '%' : 'off' }}
</small>
</template>
<span>{{ $t('Panels.ToolsPanel.Avg') }}: {{ heater.avgPower + '%' }}</span>
</v-tooltip>
</v-col>
<v-col class="py-2 text-center">
<span class="d-block">{{ heater.temperature.toFixed(1) }}°C</span>
<div v-for="(values, key) of heater.additionSensors" :key="key">
<span v-if="values.bool" class="d-block">
<small>{{ values.value }} {{ values.unit }}</small>
</span>
</div>
</v-col>
<v-col class="text-center py-2 pr-8 vertical_align_center">
<tool-input
:name="heater.name"
:target="heater.target"
:min_temp="heater.min_temp"
:max_temp="heater.max_temp"
:items="heater.presets"
command="SET_HEATER_TEMPERATURE"
attribute-name="HEATER"></tool-input>
</v-col>
</v-row>
</div>
<div v-for="(fan, index) in temperatureFans" :key="index + 99">
<v-divider class="my-2"></v-divider>
<v-row align="center">
<v-col class="flex-grow-0 py-2 pl-8 pr-0 colHeaterIcons">
<v-icon
:color="fan.target ? 'grey lighten-5' : 'grey darken-2'"
:class="fan.speed ? ' icon-rotate' : ''">
{{ mdiFan }}
</v-icon>
</v-col>
<v-col class="py-2 font-weight-bold">
<span style="cursor: pointer" @click="openHeater(fan)">{{ convertName(fan.name) }}</span>
</v-col>
<v-col
v-if="boolTempchart"
class="py-2 flex-grow-0 text-center d-none d-md-block"
style="min-width: 75px">
<div
:style="'background-color: ' + fan.chartColor + 'cc;'"
class="datasetColorSymbol d-inline-block"
@click="openHeater(fan)"></div>
</v-col>
<v-col class="py-2 text-center d-none d-md-block">
<v-tooltip top>
<template #activator="{ on, attrs }">
<small class="d-block" v-bind="attrs" v-on="on">
{{
fan.target > 0 && fan.speed > 0
? fan.speed + '%'
: fan.target > 0
? 'standby'
: 'off'
}}
</small>
</template>
<span>{{ $t('Panels.ToolsPanel.Avg') }}: {{ fan.avgSpeed + '%' }}</span>
</v-tooltip>
</v-col>
<v-col class="py-2 text-center">
<span class="d-block">{{ fan.temperature.toFixed(1) }}°C</span>
<div v-for="(values, key) of fan.additionSensors" :key="key">
<span v-if="values.bool" class="d-block">
<small>{{ values.value }} {{ values.unit }}</small>
</span>
</div>
<small
v-if="fan.rpm !== null"
:class="'d-block ' + (fan.rpm === 0 && fan.speed > 0 ? 'red--text' : '')">
{{ fan.rpm }} RPM
</small>
</v-col>
<v-col class="text-center py-2 pr-8 pr-0 vertical_align_center">
<tool-input
:name="fan.name"
:target="fan.target"
:min_temp="fan.min_temp"
:max_temp="fan.max_temp"
:items="fan.presets"
command="SET_TEMPERATURE_FAN_TARGET"
attribute-name="temperature_fan"></tool-input>
</v-col>
</v-row>
</div>
<div v-for="(sensor, index) in temperatureSensors" :key="index + 999">
<v-divider class="my-2"></v-divider>
<v-row align="center">
<v-col class="flex-grow-0 py-2 pl-8 pr-0 colHeaterIcons">
<v-icon
color="grey darken-2"
:title="
$t('Panels.ToolsPanel.Min') +
': ' +
sensor.min_temp +
'° / ' +
$t('Panels.ToolsPanel.Max') +
': ' +
sensor.max_temp +
'°'
">
{{ sensor.icon }}
</v-icon>
</v-col>
<v-col class="py-2 font-weight-bold">
<span style="cursor: pointer" @click="openHeater(sensor)">
{{ convertName(sensor.name) }}
</span>
</v-col>
<v-col
v-if="boolTempchart"
class="py-2 flex-grow-0 text-center d-none d-md-block"
style="min-width: 75px">
<div
:style="'background-color: ' + sensor.chartColor + 'CC;'"
class="datasetColorSymbol d-inline-block"
@click="openHeater(sensor)"></div>
</v-col>
<v-col class="py-2 d-none d-md-block"><span>&nbsp;</span></v-col>
<v-col class="py-2 text-center">
<v-tooltip top>
<template #activator="{ on, attrs }">
<span style="cursor: default" class="d-block px-0" v-bind="attrs" v-on="on">
{{ sensor.temperature.toFixed(1) }}°C
</span>
</template>
<span>
{{ $t('Panels.ToolsPanel.Max') }}: {{ sensor.measured_max_temp }}°C
<br />
{{ $t('Panels.ToolsPanel.Min') }}: {{ sensor.measured_min_temp }}°C
</span>
</v-tooltip>
<div v-for="(values, key) of sensor.additionSensors" :key="key">
<span v-if="values.bool" class="d-block">
<small>{{ values.value }} {{ values.unit }}</small>
</span>
</div>
</v-col>
<v-col class="text-center py-2 pr-8 vertical_align_center"><span>&nbsp;</span></v-col>
</v-row>
</div>
<v-divider v-if="boolTempchart" class="my-2"></v-divider>
<v-row v-if="boolTempchart">
<v-col class="py-0 px-3">
<temp-chart></temp-chart>
</v-col>
</v-row>
</v-container>
</v-card-text>
<v-dialog v-model="editHeater.bool" persistent :width="400">
<panel
:title="convertName(editHeater.name)"
:icon="editHeater.icon"
card-class="tools-edit-heater-dialog"
:margin-bottom="false">
<template #buttons>
<v-btn icon tile @click="editHeater.bool = false">
<v-icon>{{ mdiCloseThick }}</v-icon>
</v-btn>
</template>
<v-card-text class="pt-6">
<v-row v-for="dataset in editHeater.chartSeries" :key="dataset">
<v-col class="col-12 py-1">
<v-checkbox
v-model="editHeater['bool' + dataset.charAt(0).toUpperCase() + dataset.slice(1)]"
:label="
$t('Panels.ToolsPanel.ShowNameInChart', {
name: $t(
'Panels.ToolsPanel.Dataset.' +
dataset.charAt(0).toUpperCase() +
dataset.slice(1)
),
})
"
hide-details
class="mt-0"
@change="setVisible(dataset)"></v-checkbox>
</v-col>
</v-row>
<v-row v-for="key in Object.keys(editHeater.additionSensors)" :key="key">
<v-col class="col-12 py-1">
<v-checkbox
v-model="editHeater.additionSensors[key]['bool']"
:label="$t('Panels.ToolsPanel.ShowNameInList', { name: key })"
hide-details
class="mt-0"
@change="setVisibleAdditionalSensor(key)"></v-checkbox>
</v-col>
</v-row>
<v-row>
<v-col class="col-12 text-center pb-0">
<v-color-picker
hide-mode-switch
mode="hexa"
:value="editHeater.color"
class="mx-auto"
@update:color="setChartColor"></v-color-picker>
</v-col>
</v-row>
</v-card-text>
</panel>
</v-dialog>
</panel>
</template>
<script lang="ts">
import Component from 'vue-class-component'
import { Mixins } from 'vue-property-decorator'
import BaseMixin from '@/components/mixins/base'
import { convertName } from '@/plugins/helpers'
import ToolInput from '@/components/inputs/ToolInput.vue'
import TempChart from '@/components/charts/TempChart.vue'
import { datasetTypes } from '@/store/variables'
import { PrinterStateHeater, PrinterStateSensor, PrinterStateTemperatureFan } from '@/store/printer/types'
import { Debounce } from 'vue-debounce-decorator'
import Panel from '@/components/ui/Panel.vue'
import { GuiPresetsStatePreset } from '@/store/gui/presets/types'
import { mdiCloseThick, mdiCog, mdiFan, mdiSnowflake, mdiFire, mdiMenuDown, mdiThermometerLines } from '@mdi/js'
@Component({
components: { Panel, TempChart, ToolInput },
})
export default class ToolsPanel extends Mixins(BaseMixin) {
mdiFan = mdiFan
mdiSnowflake = mdiSnowflake
mdiCloseThick = mdiCloseThick
mdiCog = mdiCog
mdiFire = mdiFire
mdiMenuDown = mdiMenuDown
mdiThermometerLines = mdiThermometerLines
convertName = convertName
datasetTypes = datasetTypes
private editHeater: any = {
bool: false,
name: '',
icon: '',
boolTemperature: false,
boolTarget: false,
boolPower: false,
boolSpeed: false,
additionSensors: {},
color: '',
}
get presets(): GuiPresetsStatePreset[] {
return this.$store.getters['gui/presets/getPresets'] ?? []
}
get cooldownGcode(): string {
return this.$store.getters['gui/presets/getCooldownGcode']
}
get boolTempchart(): boolean {
return this.$store.state.gui.view.tempchart.boolTempchart ?? false
}
set boolTempchart(newVal: boolean) {
this.$store.dispatch('gui/saveSetting', { name: 'view.tempchart.boolTempchart', value: newVal })
}
get autoscaleTempchart(): boolean {
return this.$store.state.gui.view.tempchart.autoscale ?? false
}
set autoscaleTempchart(newVal: boolean) {
this.$store.dispatch('gui/saveSetting', { name: 'view.tempchart.autoscale', value: newVal })
}
get heaters(): PrinterStateHeater[] {
return this.$store.getters['printer/getHeaters'] ?? []
}
get temperatureFans(): PrinterStateTemperatureFan {
return this.$store.getters['printer/getTemperatureFans']
}
get temperatureSensors(): PrinterStateSensor {
return this.$store.getters['printer/getTemperatureSensors']
}
preheat(preset: GuiPresetsStatePreset): void {
for (const [name, attributes] of Object.entries(preset.values)) {
if (attributes.bool) {
let gcode = 'SET_HEATER_TEMPERATURE HEATER=' + name + ' TARGET=' + attributes.value
if (attributes.type === 'temperature_fan') {
const fanName = name.replace('temperature_fan ', '')
gcode = 'SET_TEMPERATURE_FAN_TARGET temperature_fan=' + fanName + ' TARGET=' + attributes.value
}
this.$store.dispatch('server/addEvent', { message: gcode, type: 'command' })
this.$socket.emit('printer.gcode.script', { script: gcode })
}
}
if (preset.gcode !== '') {
setTimeout(() => {
this.$store.dispatch('server/addEvent', { message: preset.gcode, type: 'command' })
this.$socket.emit('printer.gcode.script', { script: preset.gcode })
}, 100)
}
}
cooldown(): void {
this.$store.dispatch('server/addEvent', { message: this.cooldownGcode, type: 'command' })
this.$socket.emit('printer.gcode.script', { script: this.cooldownGcode })
}
openHeater(object: PrinterStateHeater | PrinterStateTemperatureFan | PrinterStateSensor): void {
this.editHeater.name = object.name
this.editHeater.icon = object.icon
this.editHeater.color = object.chartColor
this.editHeater.chartSeries = 'chartSeries' in object ? object.chartSeries : []
this.editHeater.boolTemperature = this.$store.getters['gui/getDatasetValue']({
name: object.name,
type: 'temperature',
})
this.editHeater.boolTarget = this.$store.getters['gui/getDatasetValue']({ name: object.name, type: 'target' })
this.editHeater.boolPower = this.$store.getters['gui/getDatasetValue']({ name: object.name, type: 'power' })
this.editHeater.boolSpeed = this.$store.getters['gui/getDatasetValue']({ name: object.name, type: 'speed' })
this.editHeater.additionSensors = object.additionSensors
this.editHeater.bool = true
}
setVisible(type: string): void {
const serieName = 'bool' + type.charAt(0).toUpperCase() + type.slice(1)
const value = this.editHeater[serieName]
const name = 'view.tempchart.datasetSettings.' + this.editHeater.name + '.' + type
this.$store.dispatch('gui/saveSetting', { name, value })
}
setVisibleAdditionalSensor(sensor: string): void {
const name = 'view.tempchart.datasetSettings.' + this.editHeater.name + '.additionalSensors.' + sensor
this.$store.dispatch('gui/saveSetting', { name, value: this.editHeater.additionSensors[sensor].bool })
}
@Debounce(500)
setChartColor(value: string | any): void {
if (typeof value === 'object' && 'hex' in value) value = value.hex
this.$store.commit('printer/tempHistory/setColor', { name: this.editHeater.name, value: value })
const name = 'view.tempchart.datasetSettings.' + this.editHeater.name + '.color'
this.$store.dispatch('gui/saveSetting', { name, value })
}
}
</script>

View File

@ -544,7 +544,7 @@
"Y": "Y", "Y": "Y",
"Z": "Z" "Z": "Z"
}, },
"ToolsPanel": { "TemperaturePanel": {
"AutoscaleChart": "Autoskalér diagram", "AutoscaleChart": "Autoskalér diagram",
"Avg": "Gns", "Avg": "Gns",
"Color": "Farve", "Color": "Farve",

View File

@ -561,7 +561,7 @@
"Y": "Y", "Y": "Y",
"Z": "Z" "Z": "Z"
}, },
"ToolsPanel": { "TemperaturePanel": {
"AutoscaleChart": "Autoskalierung", "AutoscaleChart": "Autoskalierung",
"Avg": "Ø", "Avg": "Ø",
"Color": "Farbe", "Color": "Farbe",

View File

@ -562,7 +562,7 @@
"Y": "Y", "Y": "Y",
"Z": "Z" "Z": "Z"
}, },
"ToolsPanel": { "TemperaturePanel": {
"AutoscaleChart": "Autoscale Chart", "AutoscaleChart": "Autoscale Chart",
"Avg": "Avg", "Avg": "Avg",
"Color": "Color", "Color": "Color",

View File

@ -534,7 +534,7 @@
"Y": "Y", "Y": "Y",
"Z": "Z" "Z": "Z"
}, },
"ToolsPanel": { "TemperaturePanel": {
"AutoscaleChart": "Autoescalar gráfico", "AutoscaleChart": "Autoescalar gráfico",
"Avg": "Promedio", "Avg": "Promedio",
"Color": "Color", "Color": "Color",

View File

@ -518,7 +518,7 @@
"Y": "Y", "Y": "Y",
"Z": "Z" "Z": "Z"
}, },
"ToolsPanel": { "TemperaturePanel": {
"AutoscaleChart": "Echelle automatique", "AutoscaleChart": "Echelle automatique",
"Avg": "Moyenne", "Avg": "Moyenne",
"Color": "Couleur", "Color": "Couleur",

View File

@ -517,7 +517,7 @@
"Y": "Y", "Y": "Y",
"Z": "Z" "Z": "Z"
}, },
"ToolsPanel": { "TemperaturePanel": {
"AutoscaleChart": "Grafikon automatikus méretezése", "AutoscaleChart": "Grafikon automatikus méretezése",
"Avg": "Átl.", "Avg": "Átl.",
"Color": "Szín", "Color": "Szín",

View File

@ -519,7 +519,7 @@
"Y": "Y", "Y": "Y",
"Z": "Z" "Z": "Z"
}, },
"ToolsPanel": { "TemperaturePanel": {
"AutoscaleChart": "Scala automaticamente il Grafico", "AutoscaleChart": "Scala automaticamente il Grafico",
"Avg": "Medio", "Avg": "Medio",
"Color": "Colore", "Color": "Colore",

View File

@ -536,7 +536,7 @@
"Y": "Y", "Y": "Y",
"Z": "Z" "Z": "Z"
}, },
"ToolsPanel": { "TemperaturePanel": {
"AutoscaleChart": "Schaal automatisch", "AutoscaleChart": "Schaal automatisch",
"Avg": "Gemiddeld", "Avg": "Gemiddeld",
"Color": "Kleur", "Color": "Kleur",

View File

@ -517,7 +517,7 @@
"Y": "Y", "Y": "Y",
"Z": "Z" "Z": "Z"
}, },
"ToolsPanel": { "TemperaturePanel": {
"AutoscaleChart": "Autoskaluj wykres", "AutoscaleChart": "Autoskaluj wykres",
"Avg": "Śred.", "Avg": "Śred.",
"Color": "Kolor", "Color": "Kolor",

View File

@ -536,7 +536,7 @@
"Y": "Y", "Y": "Y",
"Z": "Z" "Z": "Z"
}, },
"ToolsPanel": { "TemperaturePanel": {
"AutoscaleChart": "Автомасштабируемая диаграмма", "AutoscaleChart": "Автомасштабируемая диаграмма",
"Avg": "средний", "Avg": "средний",
"Color": "Цвет", "Color": "Цвет",

View File

@ -464,7 +464,7 @@
"Y": "Y", "Y": "Y",
"Z": "Z" "Z": "Z"
}, },
"ToolsPanel": { "TemperaturePanel": {
"AutoscaleChart": "自動縮放圖表", "AutoscaleChart": "自動縮放圖表",
"Avg": "平均", "Avg": "平均",
"Color": "顏色", "Color": "顏色",

View File

@ -517,7 +517,7 @@
"Y": "Y", "Y": "Y",
"Z": "Z" "Z": "Z"
}, },
"ToolsPanel": { "TemperaturePanel": {
"AutoscaleChart": "自动缩放图表", "AutoscaleChart": "自动缩放图表",
"Avg": "平均", "Avg": "平均",
"Color": "颜色", "Color": "颜色",

View File

@ -93,7 +93,7 @@ import MinSettingsPanel from '@/components/panels/MinSettingsPanel.vue'
import MiscellaneousPanel from '@/components/panels/MiscellaneousPanel.vue' import MiscellaneousPanel from '@/components/panels/MiscellaneousPanel.vue'
import PrintsettingsPanel from '@/components/panels/PrintsettingsPanel.vue' import PrintsettingsPanel from '@/components/panels/PrintsettingsPanel.vue'
import StatusPanel from '@/components/panels/StatusPanel.vue' import StatusPanel from '@/components/panels/StatusPanel.vue'
import ToolsPanel from '@/components/panels/ToolsPanel.vue' import TemperaturePanel from '@/components/panels/TemperaturePanel.vue'
import WebcamPanel from '@/components/panels/WebcamPanel.vue' import WebcamPanel from '@/components/panels/WebcamPanel.vue'
import ZoffsetPanel from '@/components/panels/ZoffsetPanel.vue' import ZoffsetPanel from '@/components/panels/ZoffsetPanel.vue'
import kebabCase from 'lodash.kebabcase' import kebabCase from 'lodash.kebabcase'
@ -110,7 +110,7 @@ import kebabCase from 'lodash.kebabcase'
MiscellaneousPanel, MiscellaneousPanel,
PrintsettingsPanel, PrintsettingsPanel,
StatusPanel, StatusPanel,
ToolsPanel, TemperaturePanel,
WebcamPanel, WebcamPanel,
ZoffsetPanel, ZoffsetPanel,
}, },

View File

@ -61,7 +61,7 @@ export const convertPanelnameToIcon = (name: string): string => {
return mdiPrinter3d return mdiPrinter3d
case 'miscellaneous': case 'miscellaneous':
return mdiDipSwitch return mdiDipSwitch
case 'tools': case 'temperature':
return mdiThermometerLines return mdiThermometerLines
case 'miniconsole': case 'miniconsole':
return mdiConsoleLine return mdiConsoleLine

View File

@ -57,7 +57,7 @@ export const getDefaultState = (): GuiState => {
{ name: 'printsettings', visible: true }, { name: 'printsettings', visible: true },
{ name: 'machine-settings', visible: true }, { name: 'machine-settings', visible: true },
{ name: 'miscellaneous', visible: true }, { name: 'miscellaneous', visible: true },
{ name: 'tools', visible: true }, { name: 'temperature', visible: true },
{ name: 'miniconsole', visible: false }, { name: 'miniconsole', visible: false },
], ],
tabletLayout1: [ tabletLayout1: [
@ -70,7 +70,7 @@ export const getDefaultState = (): GuiState => {
{ name: 'miscellaneous', visible: true }, { name: 'miscellaneous', visible: true },
], ],
tabletLayout2: [ tabletLayout2: [
{ name: 'tools', visible: true }, { name: 'temperature', visible: true },
{ name: 'miniconsole', visible: true }, { name: 'miniconsole', visible: true },
], ],
desktopLayout1: [ desktopLayout1: [
@ -83,7 +83,7 @@ export const getDefaultState = (): GuiState => {
{ name: 'miscellaneous', visible: true }, { name: 'miscellaneous', visible: true },
], ],
desktopLayout2: [ desktopLayout2: [
{ name: 'tools', visible: true }, { name: 'temperature', visible: true },
{ name: 'miniconsole', visible: true }, { name: 'miniconsole', visible: true },
], ],
widescreenLayout1: [ widescreenLayout1: [
@ -93,7 +93,7 @@ export const getDefaultState = (): GuiState => {
{ name: 'miscellaneous', visible: true }, { name: 'miscellaneous', visible: true },
], ],
widescreenLayout2: [ widescreenLayout2: [
{ name: 'tools', visible: true }, { name: 'temperature', visible: true },
{ name: 'printsettings', visible: true }, { name: 'printsettings', visible: true },
{ name: 'machine-settings', visible: true }, { name: 'machine-settings', visible: true },
], ],

View File

@ -9,8 +9,9 @@ import {
PrinterStateTemperatureFan, PrinterStateTemperatureFan,
PrinterStateMiscellaneous, PrinterStateMiscellaneous,
PrinterStateMcu, PrinterStateMcu,
PrinterStateSensor,
PrinterStateMacro, PrinterStateMacro,
PrinterStateTemperatureObject,
PrinterStateTemperatureSensor,
} from '@/store/printer/types' } from '@/store/printer/types'
import { caseInsensitiveSort, formatFrequency, getMacroParams } from '@/plugins/helpers' import { caseInsensitiveSort, formatFrequency, getMacroParams } from '@/plugins/helpers'
import { RootState } from '@/store/types' import { RootState } from '@/store/types'
@ -121,7 +122,7 @@ export const getters: GetterTree<PrinterState, RootState> = {
if (!name.startsWith('_')) { if (!name.startsWith('_')) {
heaters.push({ heaters.push({
name: name, name: name,
type: nameSplit[0], type: nameSplit[0] as PrinterStateHeater['type'],
icon: icon, icon: icon,
iconColor: color, iconColor: color,
target: Math.round(value.target * 10) / 10, target: Math.round(value.target * 10) / 10,
@ -172,7 +173,7 @@ export const getters: GetterTree<PrinterState, RootState> = {
}, },
getTemperatureSensors: (state, getters) => { getTemperatureSensors: (state, getters) => {
const sensors: PrinterStateSensor[] = [] const sensors: PrinterStateTemperatureSensor[] = []
for (const [key, value] of Object.entries(state)) { for (const [key, value] of Object.entries(state)) {
const nameSplit = key.split(' ') const nameSplit = key.split(' ')
@ -204,6 +205,99 @@ export const getters: GetterTree<PrinterState, RootState> = {
return caseInsensitiveSort(sensors, 'name') return caseInsensitiveSort(sensors, 'name')
}, },
getTemperatureObjects: (state, getters) => {
const objects: PrinterStateTemperatureObject[] = []
const heaters = getters['getHeaters']
if (heaters.length) {
heaters.forEach((heater: PrinterStateHeater) => {
objects.push({
name: heater.name,
type: heater.type,
icon: heater.icon,
iconColor: heater.target > 0 ? `${heater.chartColor}aa` : `${heater.chartColor}22`,
iconClass: '',
state: heater.target > 0 ? heater.power + '%' : 'off',
avgState: heater.avgPower + '%',
temperature: heater.temperature,
additionSensors: heater.additionSensors,
target: heater.target,
presets: heater.presets,
min_temp: heater.min_temp,
max_temp: heater.max_temp,
measured_min_temp: null,
measured_max_temp: null,
rpm: null,
rpmClass: '',
command: 'SET_HEATER_TEMPERATURE',
commandAttributeName: 'HEATER',
chartColor: heater.chartColor,
chartSeries: heater.chartSeries,
})
})
}
const temperature_fans = getters['getTemperatureFans']
if (temperature_fans.length) {
temperature_fans.forEach((fan: PrinterStateTemperatureFan) => {
objects.push({
name: fan.name,
type: 'temperature_fan',
icon: fan.icon,
iconColor: fan.target > 0 ? `${fan.chartColor}aa` : `${fan.chartColor}22`,
iconClass: fan.speed ? ' icon-rotate' : '',
state: fan.target > 0 && fan.speed > 0 ? fan.speed + '%' : fan.target > 0 ? 'standby' : 'off',
avgState: fan.avgSpeed + '%',
temperature: fan.temperature,
additionSensors: fan.additionSensors,
target: fan.target,
presets: fan.presets,
min_temp: fan.min_temp,
max_temp: fan.max_temp,
measured_min_temp: null,
measured_max_temp: null,
rpm: `${fan.rpm} RPM`,
rpmClass: fan.rpm === 0 && fan.speed > 0 ? 'red--text' : '',
command: 'SET_TEMPERATURE_FAN_TARGET',
commandAttributeName: 'TEMPERATURE_FAN',
chartColor: fan.chartColor,
chartSeries: fan.chartSeries,
})
})
}
const temperature_sensors = getters['getTemperatureSensors']
if (temperature_sensors.length) {
temperature_sensors.forEach((sensor: PrinterStateTemperatureSensor) => {
objects.push({
name: sensor.name,
type: 'temperature_sensor',
icon: sensor.icon,
iconColor: `${sensor.chartColor}aa`,
iconClass: '',
state: null,
avgState: '',
temperature: sensor.temperature,
additionSensors: sensor.additionSensors,
target: null,
presets: [],
min_temp: sensor.min_temp,
max_temp: sensor.max_temp,
measured_min_temp: sensor.measured_min_temp,
measured_max_temp: sensor.measured_max_temp,
rpm: null,
rpmClass: '',
command: null,
commandAttributeName: null,
chartColor: sensor.chartColor,
chartSeries: sensor.chartSeries,
})
})
}
return objects
},
getPartFanSpeed: (state) => { getPartFanSpeed: (state) => {
return 'fan' in state ? state.fan.speed : 0 return 'fan' in state ? state.fan.speed : 0
}, },

View File

@ -26,7 +26,7 @@ export interface PrinterState {
export interface PrinterStateHeater { export interface PrinterStateHeater {
name: string name: string
type: string type: 'extruder' | 'heater_bed' | 'heater_generic'
icon: string icon: string
iconColor: string iconColor: string
target: number target: number
@ -57,7 +57,7 @@ export interface PrinterStateTemperatureFan {
max_temp: number max_temp: number
} }
export interface PrinterStateSensor { export interface PrinterStateTemperatureSensor {
name: string name: string
temperature: number temperature: number
additionSensors: PrinterStateAdditionSensor[] additionSensors: PrinterStateAdditionSensor[]
@ -70,6 +70,30 @@ export interface PrinterStateSensor {
chartSeries: string[] chartSeries: string[]
} }
export interface PrinterStateTemperatureObject {
name: string
type: 'extruder' | 'heater_bed' | 'heater_generic' | 'temperature_fan' | 'temperature_sensor'
icon: string
iconColor: string
iconClass: string
state: string | null
avgState: string
temperature: number
additionSensors: PrinterStateAdditionSensor[]
target: number | null
presets: number[]
min_temp: number
max_temp: number
measured_min_temp: number | null
measured_max_temp: number | null
rpm: string | null
rpmClass: string
command: 'SET_HEATER_TEMPERATURE' | 'SET_TEMPERATURE_FAN_TARGET' | null
commandAttributeName: 'HEATER' | 'TEMPERATURE_FAN' | null
chartColor: string
chartSeries: string[]
}
export interface PrinterStateAdditionSensor { export interface PrinterStateAdditionSensor {
bool: boolean bool: boolean
name: string name: string

View File

@ -75,7 +75,7 @@ export const allDashboardPanels = [
'miniconsole', 'miniconsole',
'miscellaneous', 'miscellaneous',
'printsettings', 'printsettings',
'tools', 'temperature',
'webcam', 'webcam',
'zoffset', 'zoffset',
] ]