Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(history): add moonraker sensors to total statistic #1886

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions src/components/mixins/history.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import Vue from 'vue'
import Component from 'vue-class-component'

@Component
export default class HistoryMixin extends Vue {
get moonrakerHistoryFields() {
const config = this.$store.state.server.config?.config ?? {}
const sensors = Object.keys(config).filter((key) => key.startsWith('sensor '))
const historyFields: { desc: string; unit: string; provider: string; name: string; parameter: string }[] = []

sensors.forEach((configName) => {
const sensor = config[configName] ?? {}

Object.keys(sensor)
.filter((key) => key.startsWith('history_field_'))
.forEach((key) => {
const historyField = sensor[key]

historyFields.push({
desc: historyField.desc,
unit: historyField.units,
provider: configName,
parameter: historyField.parameter,
name: key,
})
})
})

return historyFields
}
}
31 changes: 3 additions & 28 deletions src/components/panels/HistoryListPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ import HistoryListPanelAddMaintenance from '@/components/dialogs/HistoryListPane
import { GuiMaintenanceStateEntry, HistoryListRowMaintenance } from '@/store/gui/maintenance/types'
import HistoryListEntryMaintenance from '@/components/panels/History/HistoryListEntryMaintenance.vue'
import HistoryListPanelDeleteSelectedDialog from '@/components/dialogs/HistoryListPanelDeleteSelectedDialog.vue'
import HistoryMixin from '@/components/mixins/history'

export type HistoryListPanelRow = HistoryListRowJob | HistoryListRowMaintenance

Expand All @@ -201,7 +202,7 @@ export interface HistoryListPanelCol {
Panel,
},
})
export default class HistoryListPanel extends Mixins(BaseMixin) {
export default class HistoryListPanel extends Mixins(BaseMixin, HistoryMixin) {
mdiCloseThick = mdiCloseThick
mdiCog = mdiCog
mdiDatabaseArrowDownOutline = mdiDatabaseArrowDownOutline
Expand Down Expand Up @@ -409,7 +410,7 @@ export default class HistoryListPanel extends Mixins(BaseMixin) {
},
]

this.moonrakerSensors.forEach((sensor) => {
this.moonrakerHistoryFields.forEach((sensor) => {
headers.push({
text: sensor.desc,
value: sensor.name,
Expand All @@ -430,32 +431,6 @@ export default class HistoryListPanel extends Mixins(BaseMixin) {
return headers
}

get moonrakerSensors() {
const config = this.$store.state.server.config?.config ?? {}
const sensors = Object.keys(config).filter((key) => key.startsWith('sensor '))
const historyFields: { desc: string; unit: string; provider: string; name: string; parameter: string }[] = []

sensors.forEach((configName) => {
const sensor = config[configName] ?? {}

Object.keys(sensor)
.filter((key) => key.startsWith('history_field_'))
.forEach((key) => {
const historyField = sensor[key]

historyFields.push({
desc: historyField.desc,
unit: historyField.units,
provider: configName,
parameter: historyField.parameter,
name: key,
})
})
})

return historyFields
}

get tableFields() {
return this.filteredHeaders.filter(
(col: any) => !['filename', 'status'].includes(col.value) && col.value !== ''
Expand Down
159 changes: 113 additions & 46 deletions src/components/panels/HistoryStatisticsPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,50 +9,10 @@
<v-col class="col-12 col-sm-6 col-md-4">
<v-simple-table>
<tbody>
<template v-if="existsSelectedJobs">
<tr>
<td>{{ $t('History.SelectedPrinttime') }}</td>
<td class="text-right">{{ formatPrintTime(selectedPrintTime, false) }}</td>
</tr>
<tr>
<td>{{ $t('History.LongestPrinttime') }}</td>
<td class="text-right">{{ formatPrintTime(selectedLongestPrintTime, false) }}</td>
</tr>
<tr>
<td>{{ $t('History.AvgPrinttime') }}</td>
<td class="text-right">{{ formatPrintTime(selectedAvgPrintTime, false) }}</td>
</tr>
<tr>
<td>{{ $t('History.SelectedFilamentUsed') }}</td>
<td class="text-right">{{ selectedFilamentUsedFormat }}</td>
</tr>
<tr>
<td>{{ $t('History.SelectedJobs') }}</td>
<td class="text-right">{{ selectedJobs.length }}</td>
</tr>
</template>
<template v-else>
<tr>
<td>{{ $t('History.TotalPrinttime') }}</td>
<td class="text-right">{{ formatPrintTime(totalPrintTime, false) }}</td>
</tr>
<tr>
<td>{{ $t('History.LongestPrinttime') }}</td>
<td class="text-right">{{ formatPrintTime(longestPrintTime, false) }}</td>
</tr>
<tr>
<td>{{ $t('History.AvgPrinttime') }}</td>
<td class="text-right">{{ formatPrintTime(avgPrintTime, false) }}</td>
</tr>
<tr>
<td>{{ $t('History.TotalFilamentUsed') }}</td>
<td class="text-right">{{ totalFilamentUsedFormat }}</td>
</tr>
<tr>
<td>{{ $t('History.TotalJobs') }}</td>
<td class="text-right">{{ totalJobsCount }}</td>
</tr>
</template>
<tr v-for="total in totals" :key="total.title">
<td>{{ total.title }}</td>
<td class="text-right">{{ total.value }}</td>
</tr>
</tbody>
</v-simple-table>
</v-col>
Expand Down Expand Up @@ -104,13 +64,14 @@ import Panel from '@/components/ui/Panel.vue'
import HistoryFilamentUsage from '@/components/charts/HistoryFilamentUsage.vue'
import HistoryPrinttimeAvg from '@/components/charts/HistoryPrinttimeAvg.vue'
import HistoryAllPrintStatusChart from '@/components/charts/HistoryAllPrintStatusChart.vue'
import { ServerHistoryStateJob } from '@/store/server/history/types'
import { ServerHistoryStateJob, ServerHistoryStateJobAuxiliaryTotal } from '@/store/server/history/types'
import { mdiChartAreaspline, mdiDatabaseArrowDownOutline } from '@mdi/js'
import { formatPrintTime } from '@/plugins/helpers'
import HistoryMixin from '@/components/mixins/history'
@Component({
components: { Panel, HistoryFilamentUsage, HistoryPrinttimeAvg, HistoryAllPrintStatusChart },
})
export default class HistoryStatisticsPanel extends Mixins(BaseMixin) {
export default class HistoryStatisticsPanel extends Mixins(BaseMixin, HistoryMixin) {
mdiChartAreaspline = mdiChartAreaspline
mdiDatabaseArrowDownOutline = mdiDatabaseArrowDownOutline
formatPrintTime = formatPrintTime
Expand Down Expand Up @@ -215,6 +176,112 @@ export default class HistoryStatisticsPanel extends Mixins(BaseMixin) {
return this.$store.state.server.history.all_loaded ?? false
}

get selectedTotals() {
const output: { title: string; value: string }[] = [
{
title: this.$t('History.SelectedPrinttime') as string,
value: this.formatPrintTime(this.selectedPrintTime, false),
},
{
title: this.$t('History.LongestPrinttime') as string,
value: this.formatPrintTime(this.selectedLongestPrintTime, false),
},
{
title: this.$t('History.AvgPrinttime') as string,
value: this.formatPrintTime(this.selectedAvgPrintTime, false),
},
{
title: this.$t('History.SelectedFilamentUsed') as string,
value: this.selectedFilamentUsedFormat,
},
{
title: this.$t('History.SelectedJobs') as string,
value: this.selectedJobs.length.toString(),
},
]

output.push(...this.auxiliarySelectedTotals)

return output
}

get auxiliarySelectedTotals() {
const output: { title: string; value: string }[] = []
this.moonrakerHistoryFields.forEach((historyField) => {
const value = this.selectedJobs.reduce((acc: number, job: ServerHistoryStateJob) => {
const historyFieldName = historyField.name.replace('history_field_', '')
const auxiliary_data = job.auxiliary_data?.find(
(auxiliary) => auxiliary.provider === historyField.provider && auxiliary.name === historyFieldName
)

if (!auxiliary_data || typeof auxiliary_data.value !== 'number') return acc

return acc + auxiliary_data.value
}, 0)

output.push({
title: historyField.desc,
value: `${Math.round(value * 1000) / 1000} ${historyField.unit}`,
})
})

return output
}

get genericTotals() {
const output: { title: string; value: string }[] = [
{
title: this.$t('History.TotalPrinttime') as string,
value: this.formatPrintTime(this.totalPrintTime, false),
},
{
title: this.$t('History.LongestPrinttime') as string,
value: this.formatPrintTime(this.longestPrintTime, false),
},
{
title: this.$t('History.AvgPrinttime') as string,
value: this.formatPrintTime(this.avgPrintTime, false),
},
{
title: this.$t('History.TotalFilamentUsed') as string,
value: this.totalFilamentUsedFormat,
},
{
title: this.$t('History.TotalJobs') as string,
value: this.totalJobsCount.toString(),
},
]

// Add auxiliary totals
output.push(...this.auxiliaryTotals)

return output
}

get auxiliaryTotals() {
const auxiliaries = this.$store.state.server.history.auxiliary_totals ?? []
const output: { title: string; value: string }[] = []

auxiliaries.forEach((auxiliary: ServerHistoryStateJobAuxiliaryTotal) => {
const historyFieldName = `history_field_${auxiliary.field}`
const historyField = this.moonrakerHistoryFields.find(
(historyField) => historyField.provider === auxiliary.provider && historyField.name === historyFieldName
)
const value = Math.round((auxiliary.total ?? 0) * 1000) / 1000

output.push({
title: historyField?.desc ?? auxiliary.field,
value: `${value} ${historyField?.unit}`,
})
})

return output
}

get totals() {
return this.existsSelectedJobs ? this.selectedTotals : this.genericTotals
}

refreshHistory() {
this.$store.dispatch('socket/addLoading', { name: 'historyLoadAll' })

Expand Down
5 changes: 5 additions & 0 deletions src/store/server/history/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ export const actions: ActionTree<ServerHistoryState, RootState> = {

getTotals({ commit }, payload) {
commit('setTotals', payload.job_totals)

const auxiliary_totals = payload.auxiliary_totals ?? []
if (auxiliary_totals.length) {
commit('setAuxiliaryTotals', auxiliary_totals)
}
},

async getHistory({ commit, dispatch, state }, payload) {
Expand Down
1 change: 1 addition & 0 deletions src/store/server/history/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export const getDefaultState = (): ServerHistoryState => {
longest_job: 0,
longest_print: 0,
},
auxiliary_totals: [],
all_loaded: false,
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/store/server/history/mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ export const mutations: MutationTree<ServerHistoryState> = {
Vue.set(state, 'job_totals', payload)
},

setAuxiliaryTotals(state, payload) {
Vue.set(state, 'auxiliary_totals', payload)
},

setHistoryNotes(state, payload) {
const job = state.jobs.find((job) => job.job_id === payload.job_id)
if (job) Vue.set(job, 'note', payload.text)
Expand Down
8 changes: 8 additions & 0 deletions src/store/server/history/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export interface ServerHistoryState {
longest_job: number
longest_print: number
}
auxiliary_totals: ServerHistoryStateJobAuxiliaryTotal[]
all_loaded: boolean
}

Expand Down Expand Up @@ -61,6 +62,13 @@ export interface ServerHistoryStateJobAuxiliaryData {
value: number | number[]
}

export interface ServerHistoryStateJobAuxiliaryTotal {
field: string
maximum: number
provider: string
total: number
}

export interface HistoryListRowJob extends ServerHistoryStateJob {
type: 'job'
select_id: string
Expand Down
Loading