diff --git a/platypush/backend/http/webapp/src/components/panels/ZigbeeMqtt/Device.vue b/platypush/backend/http/webapp/src/components/panels/ZigbeeMqtt/Device.vue index f19ba4888..9d99aebea 100644 --- a/platypush/backend/http/webapp/src/components/panels/ZigbeeMqtt/Device.vue +++ b/platypush/backend/http/webapp/src/components/panels/ZigbeeMqtt/Device.vue @@ -110,15 +110,16 @@
{{ value.description }} - Color (XY coordinates) - Color (Hue/saturation) + Color
+ :disabled="!value.writable" v-if="value.type === 'binary'" + @input="setValue(value, $event)" /> -
- - - - - - +
+
Remove Device
+
+ +
+
- - - - - - - - - - - - - - - - - - - - +
+
Force Remove Device
+
+ +
+
@@ -194,13 +183,13 @@ import Loading from "@/components/Loading"; import Slider from "@/components/elements/Slider"; import ToggleSwitch from "@/components/elements/ToggleSwitch"; import Utils from "@/Utils"; -// import {ColorConverter} from "@/components/panels/Light/color"; +import {ColorConverter} from "@/components/panels/Light/color"; export default { name: "Device", components: {ToggleSwitch, Slider, Loading}, mixins: [Utils], - emits: ['select', 'rename'], + emits: ['select', 'rename', 'remove'], props: { device: { @@ -278,6 +267,32 @@ export default { Object.entries(this.values).reduce(mergeValues, ret) return ret }, + + rgbColor() { + if (!this.displayedValues.color) + return + + const color = this.displayedValues.color.value + if (color.x != null && color.y != null) { + const converter = new ColorConverter({ + bri: [this.displayedValues.brightness?.value_min || 0, this.displayedValues.brightness?.value_max || 255], + }) + + return converter.xyToRgb(color.x, color.y, this.displayedValues.brightness.value) + } else + if (color.hue != null && (color.saturation != null || color.sat != null)) { + const satAttr = color.saturation != null ? 'saturation' : 'sat' + const converter = new ColorConverter({ + hue: [this.displayedValues.color.hue?.value_min || 0, this.displayedValues.color.hue.value_max || 65535], + sat: [this.displayedValues.color[satAttr]?.value_min || 0, this.displayedValues.color[satAttr].value_max || 255], + bri: [this.displayedValues.brightness?.value_min || 0, this.displayedValues.brightness?.value_max || 255], + }) + + return converter.hslToRgb(color.hue, color[satAttr], this.displayedValues.brightness.value) + } + + return null + }, }, methods: { @@ -310,6 +325,24 @@ export default { } }, + async remove(force) { + if (!confirm('Are you really sure that you want to remove this device from the network?')) + return + + force = !!force + this.loading = true + try { + await this.request('zigbee.mqtt.device_remove', { + device: this.device.friendly_name?.length ? this.device.friendly_name : this.device.ieee_address, + force: force, + }) + + this.$emit('remove', {device: this.device.friendly_name || this.device.ieee_address}); + } finally { + this.loading = false + } + }, + async setValue(value, event) { const request = { device: this.device.friendly_name || this.device.ieee_address, @@ -337,6 +370,46 @@ export default { request.value = event.target.value } break + + default: + if ((value.x != null && value.y != null) || (value.hue != null && (value.saturation != null || value.sat != null))) { + request.property = 'color' + const rgb = event.target.value.slice(1) + .split(/([0-9a-fA-F]{2})/) + .filter((_, i) => i % 2) + .map((i) => parseInt(i, 16)) + + if ((value.x != null && value.y != null)) { + const converter = new ColorConverter({ + bri: [this.displayedValues.brightness?.value_min || 0, this.displayedValues.brightness?.value_max || 255], + }) + + const xy = converter.rgbToXY(...rgb) + request.value = { + color: { + x: xy[0], + y: xy[1], + } + } + } else { + const satAttr = this.displayedValues.color.saturation != null ? 'saturation' : 'sat' + const converter = new ColorConverter({ + hue: [this.displayedValues.color.hue?.value_min || 0, this.displayedValues.color.hue.value_max || 65535], + sat: [this.displayedValues.color[satAttr]?.value_min || 0, this.displayedValues.color[satAttr].value_max || 255], + bri: [this.displayedValues.brightness?.value_min || 0, this.displayedValues.brightness?.value_max || 255], + }) + + const hsl = converter.rgbToHsl(...rgb) + request.value = { + brightness: hsl[2], + color: { + hue: hsl[0], + '`${satAttr}': hsl[1], + } + } + } + } + break } if (request.value == null) @@ -364,135 +437,4 @@ export default { diff --git a/platypush/backend/http/webapp/src/components/panels/ZigbeeMqtt/Group.vue b/platypush/backend/http/webapp/src/components/panels/ZigbeeMqtt/Group.vue new file mode 100644 index 000000000..1dfc02c58 --- /dev/null +++ b/platypush/backend/http/webapp/src/components/panels/ZigbeeMqtt/Group.vue @@ -0,0 +1,143 @@ + + + + + diff --git a/platypush/backend/http/webapp/src/components/panels/ZigbeeMqtt/Index.vue b/platypush/backend/http/webapp/src/components/panels/ZigbeeMqtt/Index.vue index 38b85c46c..55381c0e0 100644 --- a/platypush/backend/http/webapp/src/components/panels/ZigbeeMqtt/Index.vue +++ b/platypush/backend/http/webapp/src/components/panels/ZigbeeMqtt/Index.vue @@ -23,10 +23,7 @@ - - - @@ -43,10 +40,10 @@
No devices found on the network
- + @@ -57,16 +54,13 @@
No groups available on the network
- - - - - - - + - +