Skip to content

Commit 290bca4

Browse files
moggieukpedrolamas
andauthored
feat: Added MMU enclosure temp/humidity to UI; New EMU MMU logo (#1707)
Signed-off-by: Paul Morgan <moggieuk@gmail.com> Co-authored-by: Pedro Lamas <pedrolamas@gmail.com>
1 parent b2df8e4 commit 290bca4

10 files changed

Lines changed: 2584 additions & 29 deletions

File tree

public/img/mmu/mmu_EMU.svg

Lines changed: 2491 additions & 0 deletions
Loading

src/components/widgets/mmu/MmuCard.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ export default class MmuCard extends Mixins(StateMixin, MmuMixin) {
299299
}
300300
301301
get showClogDetection (): boolean {
302-
return !this.hasEncoder || !!this.$typedState.config.uiSettings.mmu.showClogDetection
302+
return this.hasEncoder && this.$typedState.config.uiSettings.mmu.showClogDetection
303303
}
304304
305305
get showTtgMap (): boolean {

src/components/widgets/mmu/MmuSettings.vue

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,17 @@
7777
</v-list-item-content>
7878
</v-list-item>
7979

80+
<v-list-item @click="showName = !showName">
81+
<v-list-item-action class="my-0">
82+
<v-checkbox :input-value="showName" />
83+
</v-list-item-action>
84+
<v-list-item-content>
85+
<v-list-item-title>
86+
{{ $t('app.mmu.setting.show_name') }}
87+
</v-list-item-title>
88+
</v-list-item-content>
89+
</v-list-item>
90+
8091
<v-list-item @click="showLogos = !showLogos">
8192
<v-list-item-action class="my-0">
8293
<v-checkbox :input-value="showLogos" />
@@ -158,6 +169,18 @@ export default class MmuSettings extends Mixins(StateMixin, MmuMixin) {
158169
})
159170
}
160171
172+
get showName (): boolean {
173+
return this.$typedState.config.uiSettings.mmu.showName
174+
}
175+
176+
set showName (value: boolean) {
177+
this.$typedDispatch('config/saveByPath', {
178+
path: 'uiSettings.mmu.showName',
179+
value,
180+
server: true
181+
})
182+
}
183+
161184
get showLogos (): boolean {
162185
return this.$typedState.config.uiSettings.mmu.showLogos
163186
}

src/components/widgets/mmu/MmuUnit.vue

Lines changed: 62 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -239,8 +239,16 @@
239239
@error="vendorLogo = 'HappyHare'"
240240
/>
241241
</div>
242-
<div class="unit-name">
243-
{{ unitDisplayName }}
242+
<div class="unit-info">
243+
<div class="unit-name">
244+
<span v-if="showName">{{ unitDisplayName }}</span>
245+
</div>
246+
<div
247+
v-if="unitClimateInfo"
248+
class="unit-climate"
249+
>
250+
{{ unitClimateInfo }}
251+
</div>
244252
</div>
245253
</div>
246254
</v-container>
@@ -252,6 +260,7 @@ import BrowserMixin from '@/mixins/browser'
252260
import StateMixin from '@/mixins/state'
253261
import MmuMixin from '@/mixins/mmu'
254262
import type { MmuGateDetails } from '@/types'
263+
import type { Sensor } from '@/store/printer/types'
255264
import MmuSpool from '@/components/widgets/mmu/MmuSpool.vue'
256265
import MmuGateStatus from '@/components/widgets/mmu/MmuGateStatus.vue'
257266
@@ -287,6 +296,33 @@ export default class MmuUnit extends Mixins(BrowserMixin, StateMixin, MmuMixin)
287296
return `#${this.unitIndex + 1} ${name}`
288297
}
289298
299+
get printerSensors (): Sensor[] {
300+
return this.$typedGetters['printer/getSensors']
301+
}
302+
303+
get unitClimateInfo (): string {
304+
const unit = this.unitDetails(this.unitIndex)
305+
306+
// Handle missing or quoted sensor name
307+
const sensorName = unit.environmentSensor?.replace(/^"(.*)"$/, '$1')
308+
if (!sensorName) return ''
309+
310+
const sensor = this.printerSensors.find(s => s.key === sensorName)
311+
if (!sensor) return ''
312+
313+
const parts: string[] = []
314+
315+
if (sensor.temperature != null) {
316+
parts.push(`${sensor.temperature.toFixed(0)}°C`)
317+
}
318+
319+
if (sensor.humidity != null) {
320+
parts.push(`${sensor.humidity.toFixed(0)}%`)
321+
}
322+
323+
return parts.join(' / ')
324+
}
325+
290326
get unitGateRange (): number[] {
291327
const unitDetails = this.unitDetails(this.unitIndex)
292328
return Array.from({ length: unitDetails.numGates }, (v, k) => k + unitDetails.firstGate)
@@ -321,6 +357,10 @@ export default class MmuUnit extends Mixins(BrowserMixin, StateMixin, MmuMixin)
321357
return this.spoolWidth - 8
322358
}
323359
360+
get showName (): boolean {
361+
return this.$typedState.config.uiSettings.mmu.showName
362+
}
363+
324364
get showLogos (): boolean {
325365
return this.$typedState.config.uiSettings.mmu.showLogos
326366
}
@@ -364,16 +404,12 @@ export default class MmuUnit extends Mixins(BrowserMixin, StateMixin, MmuMixin)
364404
const firstGate = gate === 0
365405
const lastGate = (gate === this.unitGateRange.length - 1 && !this.showBypass) || gate === this.TOOL_GATE_BYPASS
366406
const classes = ['gate-status-row']
367-
if (firstGate) classes.push('first-gate' + (this.isFirefox() ? '-firefox' : ''))
368-
if (lastGate) classes.push('last-gate' + (this.isFirefox() ? '-firefox' : ''))
407+
if (firstGate) classes.push('first-gate')
408+
if (lastGate) classes.push('last-gate')
369409
classes.push(this.$vuetify.theme.dark ? 'gate-status-row-dark-theme' : 'gate-status-row-light-theme')
370410
return classes
371411
}
372412
373-
isFirefox (): boolean {
374-
return navigator.userAgent.indexOf('Firefox') !== -1
375-
}
376-
377413
spoolClass (gate: number): string[] {
378414
const classes = []
379415
if ((this.editGateMap && this.editGateSelected === gate) || (!this.editGateMap && this.gate === gate)) {
@@ -469,14 +505,29 @@ export default class MmuUnit extends Mixins(BrowserMixin, StateMixin, MmuMixin)
469505
opacity: 0.7;
470506
}
471507
508+
.unit-info {
509+
display: flex;
510+
flex-direction: column;
511+
justify-content: space-between;
512+
width: 100%;
513+
}
514+
472515
.unit-name {
473516
display: flex;
474-
align-items: center;
517+
align-items: flex-end;
475518
font-size: 12px;
476519
white-space: nowrap;
477-
margin-right: -12px;
478520
overflow: hidden;
479-
padding: 0px 0px 4px 0px;
521+
padding: 4px 0 0 0;
522+
}
523+
524+
.unit-climate {
525+
font-size: 10px;
526+
white-space: nowrap;
527+
overflow: hidden;
528+
text-align: right;
529+
padding: 0px;
530+
opacity: 0.8;
480531
}
481532
482533
.gate-status-row-dark-theme {
@@ -505,22 +556,6 @@ export default class MmuUnit extends Mixins(BrowserMixin, StateMixin, MmuMixin)
505556
border-radius: 8px 8px 10px 10px;
506557
}
507558
508-
.last-gate-firefox {
509-
border-radius: 0 8px 10px 0px;
510-
padding-right: 16px;
511-
}
512-
513-
.first-gate-firefox {
514-
border-radius: 8px 0 0px 10px;
515-
margin-left: -16px;
516-
padding-left: 16px;
517-
margin-right: 16px;
518-
}
519-
520-
.first-gate-firefox.last-gate-firefox {
521-
border-radius: 8px 8px 10px 10px;
522-
}
523-
524559
.clip-spool {
525560
position: relative;
526561
margin-top: 8px;

src/locales/en.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,6 +1121,7 @@ app:
11211121
show_clog_detection: Show Clog Detection
11221122
show_details: Show Filament Details
11231123
show_ttg_map: Show TTG Map
1124+
show_name: Show Unit Name
11241125
show_logos: Show Logos
11251126
show_unavailable_spool_color: Show Unavailable Spools
11261127
sensors:

src/mixins/mmu.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ export default class MmuMixin extends Vue {
7171
requireBowdenMove: mmuMachine?.[unitRef]?.require_bowden_move ?? true,
7272
filamentAlwaysGripped: mmuMachine?.[unitRef]?.filament_always_gripped ?? false,
7373
hasBypass: mmuMachine?.[unitRef]?.has_bypass ?? false,
74-
multiGear: mmuMachine?.[unitRef]?.multi_gear ?? false
74+
multiGear: mmuMachine?.[unitRef]?.multi_gear ?? false,
75+
environmentSensor: mmuMachine?.[unitRef]?.environment_sensor ?? ''
7576
}
7677
}
7778

src/store/config/state.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ export const defaultState = (): ConfigState => {
152152
showTtgMap: true,
153153
showDetails: true,
154154
largeFilamentStatus: false,
155+
showName: true,
155156
showLogos: false,
156157
showUnavailableSpoolColor: false
157158
}

src/store/config/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ export interface MmuConfig {
6565
showTtgMap: boolean;
6666
showDetails: boolean;
6767
largeFilamentStatus: boolean;
68+
showName: boolean;
6869
showLogos: boolean;
6970
showUnavailableSpoolColor: boolean;
7071
}

src/store/printer/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,7 @@ type KlipperPrinterMmuMachineStateBaseType = {
726726
filament_always_gripped: boolean;
727727
has_bypass: boolean;
728728
multi_gear: boolean;
729+
environment_sensor?: string;
729730
};
730731
}
731732

src/types/mmu.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,5 @@ export interface MmuUnitDetails {
3131
filamentAlwaysGripped: boolean
3232
hasBypass: boolean
3333
multiGear: boolean
34+
environmentSensor: string
3435
}

0 commit comments

Comments
 (0)