platypush/platypush/backend/http/static/js/plugins/light.hue/index.js

163 lines
5.2 KiB
JavaScript

Vue.component('light-hue', {
template: '#tmpl-light-hue',
props: ['config'],
data: function() {
return {
groups: {},
lights: {},
scenes: {},
selectedGroup: undefined,
selectedScene: undefined,
selectedProperties: {
type: undefined,
id: undefined,
},
};
},
methods: {
_prepareGroups: function() {
for (const [groupId, group] of Object.entries(this.groups)) {
if (group.type !== 'Room' || group.recycle) {
delete this.groups[groupId];
continue;
}
this.groups[groupId].scenes = {};
var lights = {};
for (const lightId of this.groups[groupId].lights) {
lights[lightId] = this.lights[lightId];
}
this.groups[groupId].lights = lights;
}
},
_prepareScenes: function() {
for (const [sceneId, scene] of Object.entries(this.scenes)) {
if (scene.recycle) {
delete this.scenes[sceneId];
continue;
}
this.scenes[sceneId].groups = {};
}
},
_linkLights: function() {
// Special group for lights with no group
this.groups[-1] = {
type: undefined,
lights: {},
scenes: {},
name: "[No Group]",
recycle: false,
};
for (const [lightId, light] of Object.entries(this.lights)) {
this.lights[lightId].groups = {};
for (const [groupId, group] of Object.entries(this.groups)) {
if (lightId in group.lights) {
this.lights[lightId].groups[groupId] = group;
}
}
if (!light.groups.length) {
this.groups[-1].lights[lightId] = light;
}
}
if (!this.groups[-1].lights.length) {
delete this.groups[-1];
}
},
_linkScenes: function() {
for (const [sceneId, scene] of Object.entries(this.scenes)) {
for (const lightId of scene.lights) {
for (const [groupId, group] of Object.entries(this.lights[lightId].groups)) {
this.scenes[sceneId].groups[groupId] = group;
this.groups[groupId].scenes[sceneId] = scene;
}
}
}
},
refresh: async function() {
const getLights = request('light.hue.get_lights');
const getGroups = request('light.hue.get_groups');
const getScenes = request('light.hue.get_scenes');
[this.lights, this.groups, this.scenes] = await Promise.all([getLights, getGroups, getScenes]);
this._prepareGroups();
this._prepareScenes();
this._linkLights();
this._linkScenes();
},
updatedGroup: function(event) {
for (const light of Object.values(this.groups[this.selectedGroup].lights)) {
if (event.state.any_on === event.state.all_on) {
light.state.on = event.state.all_on;
}
for (const attr in ['bri', 'xy', 'ct']) {
if (attr in event.state) {
light.state[attr] = event.state[attr];
}
}
}
},
selectScene: async function(event) {
await request(
'light.hue.scene', {
name: event.name,
groups: [this.groups[this.selectedGroup].name],
},
);
this.selectedScene = event.id;
for (const light of Object.values(this.scenes[this.selectedScene].lights)) {
this.lights[light].state.on = true;
}
},
collapsedToggled: function(event) {
if (event.type == this.selectedProperties.type
&& event.id == this.selectedProperties.id) {
this.selectedProperties = {
type: undefined,
id: undefined,
};
} else {
this.selectedProperties = {
type: event.type,
id: event.id,
};
}
},
onUnitInput: function(event) {
var groups = this.lights[event.id].groups;
for (const [groupId, group] of Object.entries(groups)) {
if (event.on) {
this.groups[groupId].state.any_on = true;
this.groups[groupId].state.all_on = Object.values(group.lights).filter((l) => l.state.on).length === Object.values(group.lights).length;
} else {
this.groups[groupId].state.all_on = false;
this.groups[groupId].state.any_on = Object.values(group.lights).filter((l) => l.state.on).length > 0;
}
}
},
},
created: function() {
this.refresh();
},
});