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

Rework oh-knob and oh-slider, fixes #1003 #1012

Merged
merged 1 commit into from
May 16, 2021
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
5 changes: 5 additions & 0 deletions bundles/org.openhab.ui/doc/components/oh-cell.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,11 @@ A regular or expandable cell
Colors of the trend line (see <a target="_blank" class="external text-color-blue" href="https://github.com/QingWei-Li/vue-trend#props">vue-trend</a>)
</PropDescription>
</PropBlock>
<PropBlock type="TEXT" name="trendSampling" label="Trend Line Sampling">
<PropDescription>
Amount of minutes between each point of the trendline (default: 60). Affected by persistence strategies different from "every minute"
</PropDescription>
</PropBlock>
</PropGroup>
</div>

Expand Down
10 changes: 10 additions & 0 deletions bundles/org.openhab.ui/doc/components/oh-knob-card.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,16 @@ Display a knob in a card to visualize and control a quantifiable item
Size the control using percentages instead of pixels
</PropDescription>
</PropBlock>
<PropBlock type="INTEGER" name="updateInterval" label="Update Interval">
<PropDescription>
Time to wait between subsequent commands in ms (default 500)
</PropDescription>
</PropBlock>
<PropBlock type="INTEGER" name="delayStateDisplay" label="Delay State Display">
<PropDescription>
Time to wait before switching from displaying user input to displaying item state in ms (default 2000)
</PropDescription>
</PropBlock>
</PropGroup>
</div>

Expand Down
10 changes: 10 additions & 0 deletions bundles/org.openhab.ui/doc/components/oh-knob-cell.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,16 @@ A cell expanding to a knob control
Size the control using percentages instead of pixels
</PropDescription>
</PropBlock>
<PropBlock type="INTEGER" name="updateInterval" label="Update Interval">
<PropDescription>
Time to wait between subsequent commands in ms (default 500)
</PropDescription>
</PropBlock>
<PropBlock type="INTEGER" name="delayStateDisplay" label="Delay State Display">
<PropDescription>
Time to wait before switching from displaying user input to displaying item state in ms (default 2000)
</PropDescription>
</PropBlock>
</PropGroup>
</div>

Expand Down
10 changes: 10 additions & 0 deletions bundles/org.openhab.ui/doc/components/oh-knob.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,16 @@ Knob control, allow to change a number value on a circular track
Size the control using percentages instead of pixels
</PropDescription>
</PropBlock>
<PropBlock type="INTEGER" name="updateInterval" label="Update Interval">
<PropDescription>
Time to wait between subsequent commands in ms (default 500)
</PropDescription>
</PropBlock>
<PropBlock type="INTEGER" name="delayStateDisplay" label="Delay State Display">
<PropDescription>
Time to wait before switching from displaying user input to displaying item state in ms (default 2000)
</PropDescription>
</PropBlock>
<PropBlock type="TEXT" name="variable" label="Variable">
<PropDescription>
Name of the variable to set on input change
Expand Down
5 changes: 5 additions & 0 deletions bundles/org.openhab.ui/doc/components/oh-label-card.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,11 @@ Display the state of an item in a card
Colors of the trend line (see <a target="_blank" class="external text-color-blue" href="https://github.com/QingWei-Li/vue-trend#props">vue-trend</a>)
</PropDescription>
</PropBlock>
<PropBlock type="TEXT" name="trendSampling" label="Trend Line Sampling">
<PropDescription>
Amount of minutes between each point of the trendline (default: 60). Affected by persistence strategies different from "every minute"
</PropDescription>
</PropBlock>
</PropGroup>
</div>

Expand Down
5 changes: 5 additions & 0 deletions bundles/org.openhab.ui/doc/components/oh-label-cell.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,11 @@ A cell with a big label to show a short item state value
Colors of the trend line (see <a target="_blank" class="external text-color-blue" href="https://github.com/QingWei-Li/vue-trend#props">vue-trend</a>)
</PropDescription>
</PropBlock>
<PropBlock type="TEXT" name="trendSampling" label="Trend Line Sampling">
<PropDescription>
Amount of minutes between each point of the trendline (default: 60). Affected by persistence strategies different from "every minute"
</PropDescription>
</PropBlock>
</PropGroup>
</div>

Expand Down
10 changes: 10 additions & 0 deletions bundles/org.openhab.ui/doc/components/oh-slider-card.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,16 @@ Display a slider in a card to control an item
Text to append to the label while dragging the cursor
</PropDescription>
</PropBlock>
<PropBlock type="INTEGER" name="updateInterval" label="Update Interval">
<PropDescription>
Time to wait between subsequent commands in ms (default 500)
</PropDescription>
</PropBlock>
<PropBlock type="INTEGER" name="delayStateDisplay" label="Delay State Display">
<PropDescription>
Time to wait before switching from displaying user input to displaying item state in ms (default 2000)
</PropDescription>
</PropBlock>
</PropGroup>
</div>

Expand Down
10 changes: 10 additions & 0 deletions bundles/org.openhab.ui/doc/components/oh-slider-cell.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,16 @@ A cell expanding to a big vertical slider
Text to append to the label while dragging the cursor
</PropDescription>
</PropBlock>
<PropBlock type="INTEGER" name="updateInterval" label="Update Interval">
<PropDescription>
Time to wait between subsequent commands in ms (default 500)
</PropDescription>
</PropBlock>
<PropBlock type="INTEGER" name="delayStateDisplay" label="Delay State Display">
<PropDescription>
Time to wait before switching from displaying user input to displaying item state in ms (default 2000)
</PropDescription>
</PropBlock>
</PropGroup>
</div>

Expand Down
10 changes: 10 additions & 0 deletions bundles/org.openhab.ui/doc/components/oh-slider-item.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,16 @@ Display a slider control in a list
Text to append to the label while dragging the cursor
</PropDescription>
</PropBlock>
<PropBlock type="INTEGER" name="updateInterval" label="Update Interval">
<PropDescription>
Time to wait between subsequent commands in ms (default 500)
</PropDescription>
</PropBlock>
<PropBlock type="INTEGER" name="delayStateDisplay" label="Delay State Display">
<PropDescription>
Time to wait before switching from displaying user input to displaying item state in ms (default 2000)
</PropDescription>
</PropBlock>
</PropGroup>
</div>

Expand Down
10 changes: 10 additions & 0 deletions bundles/org.openhab.ui/doc/components/oh-slider.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ Slider control, allows to pick a number value on a scale
Text to append to the label while dragging the cursor
</PropDescription>
</PropBlock>
<PropBlock type="INTEGER" name="updateInterval" label="Update Interval">
<PropDescription>
Time to wait between subsequent commands in ms (default 500)
</PropDescription>
</PropBlock>
<PropBlock type="INTEGER" name="delayStateDisplay" label="Delay State Display">
<PropDescription>
Time to wait before switching from displaying user input to displaying item state in ms (default 2000)
</PropDescription>
</PropBlock>
<PropBlock type="TEXT" name="variable" label="Variable">
<PropDescription>
Name of the variable to set on input change
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,7 @@ export default () => [
pt('secondaryColor', 'Secondary Color', 'Color of the rest of the control (HTML value, default #dcdfe6)'),
pt('textColor', 'Text Color', 'Color of the value text (HTML value, default #000000)'),
pt('strokeWidth', 'Stroke Width', 'Thickness of the arcs, default 17'),
pb('responsive', 'Responsive', 'Size the control using percentages instead of pixels')
pb('responsive', 'Responsive', 'Size the control using percentages instead of pixels'),
pn('updateInterval', 'Update Interval', 'Time to wait between subsequent commands in ms (default 500)').a(),
hubsif marked this conversation as resolved.
Show resolved Hide resolved
pn('delayStateDisplay', 'Delay State Display', 'Time to wait before switching from displaying user input to displaying item state in ms (default 2000)').a()
]
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@ export default () => [
pb('scale', 'Display Scale', 'Display a scale on the slider'),
pn('scaleSteps', 'Scale steps', 'Number of (major) scale markers'),
pn('scaleSubSteps', 'Scale sub-steps', 'Number of scale minor markers between each major marker'),
pt('unit', 'Unit', 'Text to append to the label while dragging the cursor')
pt('unit', 'Unit', 'Text to append to the label while dragging the cursor'),
pn('updateInterval', 'Update Interval', 'Time to wait between subsequent commands in ms (default 500)').a(),
pn('delayStateDisplay', 'Delay State Display', 'Time to wait before switching from displaying user input to displaying item state in ms (default 2000)').a()
]
Original file line number Diff line number Diff line change
@@ -1,69 +1,20 @@
<template>
<knob-control v-bind="config" :text-color="config.textColor || ($f7.data.themeOptions.dark === 'dark') ? '#ffffff' : undefined" :value="value" @input="onChange" />
<knob-control v-bind="config" :text-color="config.textColor || ($f7.data.themeOptions.dark === 'dark') ? '#ffffff' : undefined" :value="value"
@input="sendCommandDebounced($event)" @click.native="sendCommandDebounced(value, true)" @touchend.native="sendCommandDebounced(value, true)" />
</template>

<script>
import mixin from '../widget-mixin'
import slideMixin from './slide-mixin'
import { OhKnobDefinition } from '@/assets/definitions/widgets/system'

import KnobControl from 'vue-knob-control'

export default {
mixins: [mixin],
mixins: [mixin, slideMixin],
components: {
KnobControl
},
widget: OhKnobDefinition,
data () {
return {
pendingCommand: null,
delayCommand: false,
delayUpdate: null
}
},
mounted () {
delete this.config.value
},
computed: {
value () {
if (this.config.variable) return this.context.vars[this.config.variable]
if (this.delayUpdate && this.pendingCommand) return this.pendingCommand // to keep the control reactive when operating
const value = this.context.store[this.config.item].state
// use as a brightness control for HSB values
if (value.split && value.split(',').length === 3) return parseFloat(value.split(',')[2])
return parseFloat(value)
}
},
methods: {
onChange (value) {
if (value === this.value) return
if (this.config.variable) {
this.$set(this.context.vars, this.config.variable, value)
return
}
this.pendingCommand = value
if (!this.delayCommand) {
this.delayCommand = true
this.setUpdateDelayTimout()
this.$store.dispatch('sendCommand', { itemName: this.config.item, cmd: value.toString() })
setTimeout(() => {
this.delayCommand = false
if (this.delayUpdate) clearTimeout(this.delayUpdate)
if (this.pendingCommand) {
this.setUpdateDelayTimout()
this.$store.dispatch('sendCommand', { itemName: this.config.item, cmd: this.pendingCommand.toString() })
}
}, 200)
}
},
setUpdateDelayTimout () {
if (this.delayUpdate) clearTimeout(this.delayUpdate)
this.delayUpdate = setTimeout(() => {
console.debug('End of update delay')
this.delayUpdate = null
this.pendingCommand = null
}, 2000)
}
}
widget: OhKnobDefinition
}
</script>
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<template>
<f7-range ref="rangeslider" class="oh-slider" v-bind="config" :value="value" @range:changed="onChange" :format-label="formatLabel" :format-scale-label="formatScaleLabel" />
<f7-range ref="rangeslider" class="oh-slider" v-bind="config" :value="value" :format-label="formatLabel" :format-scale-label="formatScaleLabel"
@range:change="sendCommandDebounced($event)" @click.native="sendCommandDebounced(value, true)" @touchend.native="sendCommandDebounced(value, true)" />
</template>

<style lang="stylus">
Expand All @@ -10,30 +11,22 @@

<script>
import mixin from '../widget-mixin'
import slideMixin from './slide-mixin'
import { OhSliderDefinition } from '@/assets/definitions/widgets/system'

export default {
mixins: [mixin],
mixins: [mixin, slideMixin],
widget: OhSliderDefinition,
mounted () {
delete this.config.value

// f7-range inside of masonry can get rendered faulty, as the masonry changes its breakpoint layout after being rendered
// re-calculate the range slider after masonry is updated
setTimeout(() => {
this.$refs.rangeslider.f7Range.calcSize()
this.$refs.rangeslider.f7Range.layout()
if (this.$refs.rangeslider) {
this.$refs.rangeslider.f7Range.calcSize()
this.$refs.rangeslider.f7Range.layout()
}
}, 0)
},
computed: {
value () {
if (this.config.variable) return this.context.vars[this.config.variable]
const value = this.context.store[this.config.item].state
// use as a brightness control for HSB values
if (value.split && value.split(',').length === 3) return parseFloat(value.split(',')[2])
return parseFloat(value)
}
},
methods: {
formatLabel (value) {
return this.toStepFixed(value) + (this.config.unit || '')
Expand All @@ -45,15 +38,6 @@ export default {
// uses the number of decimals in the step config to round the provided number
const nbDecimals = this.config.step ? Number(this.config.step).toString().replace(',', '.').split('.')[1] : 0
return parseFloat(Number(value).toFixed(nbDecimals))
},
onChange (value) {
const newValue = this.toStepFixed(value)
if (newValue === this.toStepFixed(this.value)) return
if (this.config.variable) {
this.$set(this.context.vars, this.config.variable, value)
} else if (this.config.item) {
this.$store.dispatch('sendCommand', { itemName: this.config.item, cmd: newValue.toString() })
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
export default {
data () {
return {
pendingCommand: null
}
},
mounted () {
delete this.config.value

this.updateInterval = this.config.updateInterval ? this.config.updateInterval : 200
this.delayStateDisplay = this.config.delayStateDisplay ? this.config.delayStateDisplay : 2000
},
computed: {
value () {
if (this.config.variable) return this.context.vars[this.config.variable]
if (this.pendingCommand) return this.pendingCommand // to keep the control reactive when operating
const value = this.context.store[this.config.item].state
// use as a brightness control for HSB values
if (value.split && value.split(',').length === 3) return parseFloat(value.split(',')[2])
return parseFloat(value)
}
},
methods: {
sendCommandDebounced (value, stop = false) {
if ((value === this.value && !stop) || value === this.lastValueSent) return

if (this.config.variable) {
this.$set(this.context.vars, this.config.variable, value)
return
}

if (!this.config.item) return

this.pendingCommand = value
let diff = this.lastDateSent ? Date.now() - this.lastDateSent : this.updateInterval
let delay = diff < this.updateInterval ? this.updateInterval - diff : stop ? 0 : this.updateInterval

if (this.sendCommandTimer && stop) {
clearTimeout(this.sendCommandTimer)
this.sendCommandTimer = null
}
if (!this.sendCommandTimer) {
if (this.displayLockTimer) clearTimeout(this.displayLockTimer)
this.sendCommandTimer = setTimeout(() => {
this.$store.dispatch('sendCommand', { itemName: this.config.item, cmd: this.pendingCommand.toString() })
this.lastValueSent = this.pendingCommand
this.lastDateSent = Date.now()
this.sendCommandTimer = null

// keep displaying `pendingCommand` as value for `delayStateDisplay` time to give sse state some time to update
this.displayLockTimer = setTimeout(() => { this.pendingCommand = null }, this.delayStateDisplay)
}, delay)
}
}
}
}