platypush/platypush/backend/http/static/js/plugins/zigbee.mqtt/index.js

319 lines
11 KiB
JavaScript

Vue.component('zigbee-mqtt', {
template: '#tmpl-zigbee-mqtt',
props: ['config'],
data: function() {
return {
bus: new Vue({}),
status: {},
devices: {},
groups: {},
commandRunning: false,
selected: {
view: 'devices',
deviceId: undefined,
groupId: undefined,
},
loading: {
status: false,
devices: false,
groups: false,
},
views: {
devices: true,
groups: true,
},
modal: {
group: {
visible: false,
},
},
};
},
computed: {
networkDropdownItems: function() {
const self = this;
return [
{
text: 'Start Network',
disabled: this.commandRunning,
click: async function() {
self.commandRunning = true;
await request('zigbee.mqtt.start_network');
self.commandRunning = false;
},
},
{
text: 'Stop Network',
disabled: this.commandRunning,
click: async function() {
self.commandRunning = true;
await request('zigbee.mqtt.stop_network');
self.commandRunning = false;
},
},
{
text: 'Permit Join',
disabled: this.commandRunning,
click: async function() {
let seconds = prompt('Join allow period in seconds (type 0 for no time limits)', '60');
if (!seconds) {
return;
}
seconds = parseInt(seconds);
self.commandRunning = true;
await request('zigbee.mqtt.permit_join', {permit: true, timeout: seconds || null});
self.commandRunning = false;
},
},
{
text: 'Reset',
disabled: this.commandRunning,
click: async function() {
if (!confirm('Are you sure that you want to reset the device?')) {
return;
}
await request('zigbee.mqtt.reset');
},
},
{
text: 'Factory Reset',
disabled: this.commandRunning,
classes: ['error'],
click: async function() {
if (!confirm('Are you sure that you want to do a device soft reset? ALL network information and custom firmware will be lost!!')) {
return;
}
await request('zigbee.mqtt.factory_reset');
},
},
]
},
addToGroupDropdownItems: function() {
const self = this;
return Object.values(this.groups).filter((group) => {
return !group.values || !group.values.length || !(this.selected.valueId in this.scene.values);
}).map((group) => {
return {
text: group.name,
disabled: this.commandRunning,
click: async function () {
if (!self.selected.valueId) {
return;
}
self.commandRunning = true;
await request('zwave.scene_add_value', {
id_on_network: self.selected.valueId,
scene_id: group.scene_id,
});
self.commandRunning = false;
self.refresh();
},
};
});
},
},
methods: {
refreshDevices: async function () {
const self = this;
this.loading.devices = true;
this.devices = (await request('zigbee.mqtt.devices')).reduce((devices, device) => {
if (device.friendly_name in self.devices) {
device = {
values: self.devices[device.friendly_name].values || {},
...self.devices[device.friendly_name],
}
}
devices[device.friendly_name] = device;
return devices;
}, {});
Object.values(this.devices).forEach((device) => {
if (device.type === 'Coordinator') {
return;
}
request('zigbee.mqtt.device_get', {device: device.friendly_name}).then((response) => {
Vue.set(self.devices[device.friendly_name], 'values', response || {});
});
});
this.loading.devices = false;
},
refreshGroups: async function () {
this.loading.groups = true;
this.groups = (await request('zigbee.mqtt.groups')).reduce((groups, group) => {
groups[group.id] = group;
return groups;
}, {});
this.loading.groups = false;
},
refresh: function () {
this.refreshDevices();
this.refreshGroups();
this.bus.$emit('refreshProperties');
},
updateProperties: function(device, props) {
Vue.set(this.devices[device], 'values', props);
},
addGroup: async function() {
const name = prompt('Group name');
if (!name) {
return;
}
this.commandRunning = true;
await request('zigbee.mqtt.group_add', {name: name});
this.commandRunning = false;
this.refreshGroups();
},
onViewChange: function(event) {
Vue.set(this.selected, 'view', event.target.value);
},
onDeviceClicked: function(event) {
Vue.set(this.selected, 'deviceId', event.deviceId === this.selected.deviceId ? undefined : event.deviceId);
},
onGroupClicked: function(event) {
Vue.set(this.selected, 'groupId', event.groupId === this.selected.groupId ? undefined : event.groupId);
},
openNetworkCommandsDropdown: function() {
openDropdown(this.$refs.networkCommandsDropdown);
},
openAddToGroupDropdown: function(event) {
this.selected.valueId = event.valueId;
openDropdown(this.$refs.addToGroupDropdown);
},
addToGroup: async function(device, group) {
this.commandRunning = true;
await request('zigbee.mqtt.group_add_device', {
device: device,
group: group,
});
this.commandRunning = false;
const self = this;
setTimeout(() => {
self.refresh();
self.bus.$emit('refreshProperties');
}, 100)
},
removeNodeFromGroup: async function(event) {
if (!confirm('Are you sure that you want to remove this value from the group?')) {
return;
}
this.commandRunning = true;
await request('zigbee.mqtt.group_remove_device', {
group: event.group,
device: event.device,
});
this.commandRunning = false;
},
},
created: function() {
const self = this;
this.bus.$on('refresh', this.refresh);
this.bus.$on('refreshDevices', this.refreshDevices);
this.bus.$on('refreshGroups', this.refreshGroups);
this.bus.$on('deviceClicked', this.onDeviceClicked);
this.bus.$on('groupClicked', this.onGroupClicked);
this.bus.$on('openAddToGroupModal', () => {self.modal.group.visible = true});
this.bus.$on('openAddToGroupDropdown', this.openAddToGroupDropdown);
this.bus.$on('removeFromGroup', this.removeNodeFromGroup);
registerEventHandler(() => {
createNotification({
text: 'WARNING: The controller is now offline',
error: true,
});
}, 'platypush.message.event.zigbee.mqtt.ZigbeeMqttOnlineEvent');
registerEventHandler(() => {
createNotification({
text: 'Failed to remove the device',
error: true,
});
}, 'platypush.message.event.zigbee.mqtt.ZigbeeMqttDeviceRemovedFailedEvent');
registerEventHandler(() => {
createNotification({
text: 'Failed to add the group',
error: true,
});
}, 'platypush.message.event.zigbee.mqtt.ZigbeeMqttGroupAddedFailedEvent');
registerEventHandler(() => {
createNotification({
text: 'Failed to remove the group',
error: true,
});
}, 'platypush.message.event.zigbee.mqtt.ZigbeeMqttGroupRemovedFailedEvent');
registerEventHandler(() => {
createNotification({
text: 'Failed to remove the devices from the group',
error: true,
});
}, 'platypush.message.event.zigbee.mqtt.ZigbeeMqttGroupRemoveAllFailedEvent');
registerEventHandler((event) => {
createNotification({
text: 'Unhandled Zigbee error: ' + (event.error || '[Unknown error]'),
error: true,
});
}, 'platypush.message.event.zigbee.mqtt.ZigbeeMqttErrorEvent');
registerEventHandler((event) => {
self.updateProperties(event.device, event.properties);
}, 'platypush.message.event.zigbee.mqtt.ZigbeeMqttDevicePropertySetEvent');
registerEventHandler(this.refresh,
'platypush.message.event.zigbee.mqtt.ZigbeeMqttOnlineEvent',
'platypush.message.event.zigbee.mqtt.ZigbeeMqttDevicePairingEvent',
'platypush.message.event.zigbee.mqtt.ZigbeeMqttDeviceConnectedEvent',
'platypush.message.event.zigbee.mqtt.ZigbeeMqttDeviceBannedEvent',
'platypush.message.event.zigbee.mqtt.ZigbeeMqttDeviceRemovedEvent',
'platypush.message.event.zigbee.mqtt.ZigbeeMqttDeviceWhitelistedEvent',
'platypush.message.event.zigbee.mqtt.ZigbeeMqttDeviceRenamedEvent',
'platypush.message.event.zigbee.mqtt.ZigbeeMqttDeviceBindEvent',
'platypush.message.event.zigbee.mqtt.ZigbeeMqttDeviceUnbindEvent',
'platypush.message.event.zigbee.mqtt.ZigbeeMqttGroupAddedEvent',
'platypush.message.event.zigbee.mqtt.ZigbeeMqttGroupRemovedEvent',
'platypush.message.event.zigbee.mqtt.ZigbeeMqttGroupRemoveAllEvent',
);
},
mounted: function() {
this.refresh();
},
});