diff --git a/bundles/org.openhab.ui/web/src/components/item/group-form.vue b/bundles/org.openhab.ui/web/src/components/item/group-form.vue index ca541376cb..75da05261d 100644 --- a/bundles/org.openhab.ui/web/src/components/item/group-form.vue +++ b/bundles/org.openhab.ui/web/src/components/item/group-form.vue @@ -107,7 +107,7 @@ export default { const dimension = this.dimensions.find((d) => d.name === newDimension) this.$set(this.item, 'groupType', 'Number:' + dimension.name) this.groupUnit = this.getUnitHint(dimension.name) - this.$set(this.item, 'stateDescriptionPattern', this.getStateDescription()) + this.$set(this.item, 'stateDescriptionPattern', this.stateDescriptionPattern) } }, groupUnit: { diff --git a/bundles/org.openhab.ui/web/src/components/item/item-form.vue b/bundles/org.openhab.ui/web/src/components/item/item-form.vue index 3952314066..a970179772 100644 --- a/bundles/org.openhab.ui/web/src/components/item/item-form.vue +++ b/bundles/org.openhab.ui/web/src/components/item/item-form.vue @@ -40,11 +40,11 @@ + :clear-button="createMode" /> @@ -98,7 +98,7 @@ import uomMixin from '@/components/item/uom-mixin' export default { mixins: [ItemMixin, uomMixin], - props: ['item', 'items', 'createMode', 'hideCategory', 'hideType', 'hideSemantics', 'forceSemantics', 'unitHint'], + props: ['item', 'items', 'createMode', 'hideCategory', 'hideType', 'hideSemantics', 'forceSemantics', 'unitHint', 'stateDescription'], components: { SemanticsPicker, ItemPicker, @@ -149,7 +149,6 @@ export default { const dimension = this.dimensions.find((d) => d.name === newDimension) this.$set(this.item, 'type', 'Number:' + dimension.name) this.itemUnit = (this.unitHint ? this.unitHint : this.getUnitHint(dimension.name)) - this.$set(this.item, 'stateDescription', this.getStateDescription()) } }, itemUnit: { @@ -171,7 +170,7 @@ export default { stateDescriptionPattern: { get () { if (this.item.stateDescriptionPattern) return this.item.stateDescriptionPattern - return this.item.metadata?.stateDescription?.config.pattern || '%.0f %unit%' + return this.item.metadata?.stateDescription?.config.pattern || this.stateDescription || (this.createMode ? '%.0f %unit%' : '') }, set (newPattern) { this.$set(this.item, 'stateDescriptionPattern', newPattern) @@ -275,6 +274,11 @@ export default { if (!this.item) return this.initializeAutocompleteCategory() if (this.dimensionsReady) this.initializeAutocompleteUnit() + if (this.createMode && this.stateDescription && (this.stateDescription !== this.item.stateDescriptionPattern)) { + // If there is a state description from the channel type that is different from the default, + // set it as the item state description + this.item.stateDescriptionPattern = this.stateDescription + } }, beforeDestroy () { if (this.unitAutocomplete) { diff --git a/bundles/org.openhab.ui/web/src/components/item/item-mixin.js b/bundles/org.openhab.ui/web/src/components/item/item-mixin.js index ee97df29ce..80fe394531 100644 --- a/bundles/org.openhab.ui/web/src/components/item/item-mixin.js +++ b/bundles/org.openhab.ui/web/src/components/item/item-mixin.js @@ -64,36 +64,42 @@ export default { const stateDescriptionPattern = item.stateDescriptionPattern delete item.stateDescriptionPattern - // TODO: Add support for saving metadata return this.$oh.api.put('/rest/items/' + item.name, item).then(() => { - // Save unit metadata if Item is an UoM Item - if ((item.type.startsWith('Number:') || item.groupType?.startsWith('Number:')) && unit) { - const metadata = { - value: unit, - config: {} - } - return this.$oh.api.put('/rest/items/' + item.name + '/metadata/unit', metadata) - } else { - return Promise.resolve() - } + return this.saveUnit(item, unit) }).then(() => { - // Save state description if Item is an UoM Item and if state description changed from the default value - if ((item.type.startsWith('Number:') || item.groupType?.startsWith('Number:')) && stateDescriptionPattern) { - if (stateDescriptionPattern !== '%.0f %unit%') { - const metadata = { - value: ' ', - config: { - pattern: stateDescriptionPattern - } - } - return this.$oh.api.put('/rest/items/' + item.name + '/metadata/stateDescription', metadata) - } - } else { - return Promise.resolve() - } + return this.saveStateDescription(item, stateDescriptionPattern) }).catch((err) => { return Promise.reject(err) }) + }, + saveUnit (item, unit) { + // Save unit metadata if Item is an UoM Item + if ((item.type.startsWith('Number:') || item.groupType?.startsWith('Number:')) && unit) { + const metadata = { + value: unit, + config: {} + } + return this.saveMetaData(item, 'unit', metadata) + } else { + return Promise.resolve() + } + }, + saveStateDescription (item, stateDescriptionPattern) { + // Save state description if Item is an UoM Item + if ((item.type.startsWith('Number:') || item.groupType?.startsWith('Number:')) && stateDescriptionPattern) { + const metadata = { + value: ' ', + config: { + pattern: stateDescriptionPattern + } + } + return this.saveMetaData(item, 'stateDescription', metadata) + } else { + return Promise.resolve() + } + }, + saveMetaData (item, value, metadata) { + return this.$oh.api.put('/rest/items/' + item.name + '/metadata/' + value, metadata) } } } diff --git a/bundles/org.openhab.ui/web/src/components/thing/channel-list.vue b/bundles/org.openhab.ui/web/src/components/thing/channel-list.vue index 413c8fb25b..04191bde2a 100644 --- a/bundles/org.openhab.ui/web/src/components/thing/channel-list.vue +++ b/bundles/org.openhab.ui/web/src/components/thing/channel-list.vue @@ -48,7 +48,14 @@ @channel-updated="(e) => $emit('channels-updated', e)" /> @@ -200,6 +207,7 @@ export default { category: (channelType) ? channelType.category : '', type: channel.itemType, unit: this.channelUnit(channel, channelType), + stateDescriptionPattern: '', tags: (defaultTags.find((t) => this.$store.getters.semanticClasses.Points.indexOf(t) >= 0)) ? defaultTags : [...defaultTags, 'Point'] } this.newItems.push(newItem) @@ -209,6 +217,9 @@ export default { const dimension = channel.itemType.startsWith('Number:') ? channel.itemType.split(':')[1] : '' return dimension ? this.getUnitHint(dimension, channelType) : '' }, + stateDescription (channelType) { + return channelType?.stateDescription?.pattern + }, toggleAllChecks (checked) { this.thing.channels.forEach((c) => { const channelType = this.channelTypesMap.get(c.channelTypeUID) diff --git a/bundles/org.openhab.ui/web/src/pages/settings/model/add-from-thing.vue b/bundles/org.openhab.ui/web/src/pages/settings/model/add-from-thing.vue index 54cf485fe8..99be7a9af3 100644 --- a/bundles/org.openhab.ui/web/src/pages/settings/model/add-from-thing.vue +++ b/bundles/org.openhab.ui/web/src/pages/settings/model/add-from-thing.vue @@ -97,11 +97,12 @@ import ItemForm from '@/components/item/item-form.vue' import Item from '@/components/item/item.vue' import ThingStatus from '@/components/thing/thing-status-mixin' +import ItemMixin from '@/components/item/item-mixin' import generateTextualDefinition from './generate-textual-definition' export default { - mixins: [ThingStatus], + mixins: [ThingStatus, ItemMixin], components: { Item, ThingPicker, @@ -190,33 +191,47 @@ export default { let copy = Object.assign({}, p) delete (copy.channel) delete (copy.channelType) + delete (copy.unit) + delete (copy.stateDescriptionPattern) return copy })] if (this.createEquipment) payload.unshift(this.newEquipmentItem) this.$oh.api.put('/rest/items/', payload).then((data) => { - dialog.setText('Creating links...') - dialog.setProgress(50) - const linkPromises = this.newPointItems.map((p) => { - return this.$oh.api.put(`/rest/links/${p.name}/${encodeURIComponent(p.channel.uid)}`, { - itemName: p.name, - channelUID: p.channel.uid, - configuration: {} - }) + dialog.setText('Updating unit metadata...') + dialog.setProgress(40) + const unitPromises = this.newPointItems.map((p) => { + return this.saveUnit(p, p.unit).then(() => { return this.saveStateDescription(p, p.stateDescriptionPattern) }) }) - Promise.all(linkPromises).then((data) => { - dialog.setProgress(100) - this.$f7.toast.create({ - text: 'Items created and linked', - destroyOnClose: true, - closeTimeout: 2000 - }).open() - dialog.close() - this.$f7router.back() + Promise.all(unitPromises).then((data) => { + dialog.setText('Creating links...') + dialog.setProgress(60) + const linkPromises = this.newPointItems.map((p) => { + return this.$oh.api.put(`/rest/links/${p.name}/${encodeURIComponent(p.channel.uid)}`, { + itemName: p.name, + channelUID: p.channel.uid, + configuration: {} + }) + }) + + Promise.all(linkPromises).then((data) => { + dialog.setProgress(100) + this.$f7.toast.create({ + text: 'Items created and linked', + destroyOnClose: true, + closeTimeout: 2000 + }).open() + dialog.close() + this.$f7router.back() + }).catch((err) => { + dialog.close() + console.error(err) + this.$f7.dialog.alert('An error occurred while creating the links: ' + err) + }) }).catch((err) => { dialog.close() console.error(err) - this.$f7.dialog.alert('An error occurred while creating the links: ' + err) + this.$f7.dialog.alert('An error occurred while creating unit metadata: ' + err) }) }).catch((err) => { dialog.close() diff --git a/bundles/org.openhab.ui/web/src/pages/settings/things/link/link-add.vue b/bundles/org.openhab.ui/web/src/pages/settings/things/link/link-add.vue index 102fdd7c23..1ffa56de1d 100644 --- a/bundles/org.openhab.ui/web/src/pages/settings/things/link/link-add.vue +++ b/bundles/org.openhab.ui/web/src/pages/settings/things/link/link-add.vue @@ -43,7 +43,7 @@ - + @@ -207,6 +207,9 @@ export default { const dimension = this.channel.itemType.startsWith('Number:') ? this.channel.itemType.split(':')[1] : '' return dimension ? this.getUnitHint(dimension, this.channelType) : '' }, + stateDescription () { + return this.channelType?.stateDescription?.pattern + }, loadProfileTypes (channel) { this.ready = false this.selectedChannel = channel