Working with all lights
This commit is contained in:
parent
eacd56afa5
commit
a43ecd2700
@ -26,6 +26,7 @@ export class FluxAccessory implements IAccessory {
|
|||||||
private _homebridge: any;
|
private _homebridge: any;
|
||||||
private _log: any = {};
|
private _log: any = {};
|
||||||
private _config: IConfig;
|
private _config: IConfig;
|
||||||
|
private _isActive: boolean;
|
||||||
|
|
||||||
//Service fields
|
//Service fields
|
||||||
private _switchService: HAPNodeJS.Service;
|
private _switchService: HAPNodeJS.Service;
|
||||||
@ -35,8 +36,6 @@ export class FluxAccessory implements IAccessory {
|
|||||||
|
|
||||||
private _lights: Array<Light> = [];
|
private _lights: Array<Light> = [];
|
||||||
|
|
||||||
private _scheduler: Scheduler;
|
|
||||||
|
|
||||||
private _times: GetTimesResult;
|
private _times: GetTimesResult;
|
||||||
|
|
||||||
constructor(props: IFluxProps) {
|
constructor(props: IFluxProps) {
|
||||||
@ -47,10 +46,7 @@ export class FluxAccessory implements IAccessory {
|
|||||||
Service = props.api.hap.Service;
|
Service = props.api.hap.Service;
|
||||||
Characteristic = props.api.hap.Characteristic;
|
Characteristic = props.api.hap.Characteristic;
|
||||||
this._homebridge = props.homebridge;
|
this._homebridge = props.homebridge;
|
||||||
this._scheduler = new Scheduler(
|
this._isActive = false;
|
||||||
this._config.delay ? this._config.delay : 60000,
|
|
||||||
this._config.watchdog ? this._config.watchdog : 120000, this._log);
|
|
||||||
this._scheduler.addTask({ delegate: this.updateDelegate, title: "Update" })
|
|
||||||
|
|
||||||
this._hue = props.hue;
|
this._hue = props.hue;
|
||||||
this.name = this._config.name;
|
this.name = this._config.name;
|
||||||
@ -89,9 +85,9 @@ export class FluxAccessory implements IAccessory {
|
|||||||
private onSetEnabled = async (activeState: boolean, callback: (error?: Error | null | undefined) => void) => {
|
private onSetEnabled = async (activeState: boolean, callback: (error?: Error | null | undefined) => void) => {
|
||||||
if (activeState) {
|
if (activeState) {
|
||||||
this._times = getTimes(new Date(), this._config.latitude, this._config.longitude);
|
this._times = getTimes(new Date(), this._config.latitude, this._config.longitude);
|
||||||
this._scheduler.start();
|
this.update();
|
||||||
} else {
|
} else {
|
||||||
this._scheduler.stop();
|
this._isActive = false;
|
||||||
}
|
}
|
||||||
return callback();
|
return callback();
|
||||||
}
|
}
|
||||||
@ -101,7 +97,7 @@ export class FluxAccessory implements IAccessory {
|
|||||||
* @param callback The callback function to call when complete
|
* @param callback The callback function to call when complete
|
||||||
*/
|
*/
|
||||||
private onGetEnabled = (callback: (error: Error | null, value: boolean) => void) => {
|
private onGetEnabled = (callback: (error: Error | null, value: boolean) => void) => {
|
||||||
return callback(null, this._scheduler.IsStarted);
|
return callback(null, this._isActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -115,14 +111,13 @@ export class FluxAccessory implements IAccessory {
|
|||||||
/**
|
/**
|
||||||
* Popuplates internal lights array using the configuration values
|
* Popuplates internal lights array using the configuration values
|
||||||
*/
|
*/
|
||||||
private getLights = async () => {
|
private getLights = async (): Promise<void> => {
|
||||||
//Get lights
|
for (const value of this._config.lights) {
|
||||||
const lightPromises: Array<Promise<void>> = this._config.lights.map(async (value: string) => {
|
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
const light: Light = await this._hue.lights.getLightByName(value)
|
const light: Light = await this._hue.lights.getLightByName(value)
|
||||||
this._lights.push(light);
|
this._lights.push(light);
|
||||||
});
|
this._log(`Got light ${light.name}`);
|
||||||
await Promise.all(lightPromises);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private colorTempToRgb = (kelvin: number): { red: number, green: number, blue: number } => {
|
private colorTempToRgb = (kelvin: number): { red: number, green: number, blue: number } => {
|
||||||
@ -166,19 +161,17 @@ export class FluxAccessory implements IAccessory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private setLights = async (state: LightState) => {
|
private setLights = async (state: LightState) => {
|
||||||
const promises = this._lights.map(async (value: Light) => {
|
// const promises: Array<Promise<unknown> | PromiseLike<unknown>> = [];
|
||||||
|
for (const light of this._lights) {
|
||||||
try {
|
try {
|
||||||
await this._hue.lights.setLightState(value.id, state);
|
this._log(`Setting light ${light.name}`);
|
||||||
|
await this._hue.lights.setLightState(light.id, state);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if ((this.isHueError(err)) && err.message === "parameter, xy, is not modifiable. Device is set to off.") {
|
this._log(`Error while setting lights: ${err}`);
|
||||||
//Eat this
|
|
||||||
} else {
|
|
||||||
this._log(`Error while setting lights: ${err}`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
await Promise.all(promises);
|
// await Promise.all(promises);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -196,99 +189,103 @@ export class FluxAccessory implements IAccessory {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateDelegate: Delegate = async (): Promise<void> => {
|
private update = async (): Promise<void> => {
|
||||||
if (this._lights.length === 0) {
|
this._isActive = true;
|
||||||
await this.getLights();
|
while (this._isActive) {
|
||||||
}
|
if (this._lights.length === 0) {
|
||||||
|
await this.getLights();
|
||||||
const now = new Date(Date.now());
|
|
||||||
const sunset = this._times.sunset;
|
|
||||||
|
|
||||||
let startTime: Date;
|
|
||||||
if (this._config.startTimeHour) {
|
|
||||||
startTime = new Date(Date.now());
|
|
||||||
startTime.setHours(this._config.startTimeHour, this._config.startTimeMinute);
|
|
||||||
} else {
|
|
||||||
startTime = this._times.sunrise;
|
|
||||||
}
|
|
||||||
|
|
||||||
let stopTime: Date;
|
|
||||||
if (this._config.stopTimeHour) {
|
|
||||||
stopTime = new Date(Date.now());
|
|
||||||
stopTime.setHours(this._config.stopTimeHour, this._config.stopTimeMinute);
|
|
||||||
} else {
|
|
||||||
stopTime = this._times.dusk;
|
|
||||||
}
|
|
||||||
|
|
||||||
const startColorTemp = this._config.startColorTemp ? this._config.startColorTemp : 4000;
|
|
||||||
const stopColorTemp = this._config.stopColorTemp ? this._config.stopColorTemp : 1900;
|
|
||||||
const sunsetColorTemp = this._config.sunsetColorTemp ? this._config.sunsetColorTemp : 3000;
|
|
||||||
|
|
||||||
let percentageComplete = 0;
|
|
||||||
let newTemp = 0;
|
|
||||||
|
|
||||||
//Adjust for next day times
|
|
||||||
if (stopTime <= startTime) {
|
|
||||||
//Stop time does not happen in the same day as start time
|
|
||||||
if (startTime < now) {
|
|
||||||
//stop time is tomorrow
|
|
||||||
stopTime.setTime(stopTime.getTime() + 1 * 86400000);
|
|
||||||
}
|
}
|
||||||
} else if (now < startTime) {
|
|
||||||
//Stop time was yesterday since the new start time is not reached
|
|
||||||
stopTime.setTime(stopTime.getTime() - 1 * 86400000);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((startTime < now) && (now < sunset)) {
|
const now = new Date(Date.now());
|
||||||
//Before sunset; calculate temp based on TOD
|
const sunset = this._times.sunset;
|
||||||
const tempRange = Math.abs(startColorTemp - stopColorTemp);
|
|
||||||
const dayLength = (sunset.getTime() - startTime.getTime()) / 1000;
|
|
||||||
const secondsFromStart = (now.getTime() - startTime.getTime()) / 1000;
|
|
||||||
percentageComplete = secondsFromStart / dayLength;
|
|
||||||
const tempOffset = tempRange * percentageComplete;
|
|
||||||
|
|
||||||
if (startColorTemp > sunsetColorTemp) {
|
let startTime: Date;
|
||||||
newTemp = startColorTemp - tempOffset;
|
if (this._config.startTimeHour) {
|
||||||
|
startTime = new Date(Date.now());
|
||||||
|
startTime.setHours(this._config.startTimeHour, this._config.startTimeMinute);
|
||||||
} else {
|
} else {
|
||||||
newTemp = startColorTemp + tempOffset;
|
startTime = this._times.sunrise;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
//After sunset; calculate temp based on TOD
|
let stopTime: Date;
|
||||||
if (now < stopTime) {
|
if (this._config.stopTimeHour) {
|
||||||
let sunsetTime;
|
stopTime = new Date(Date.now());
|
||||||
if ((stopTime < startTime) && stopTime.getDay() == sunset.getDay()) {
|
stopTime.setHours(this._config.stopTimeHour, this._config.stopTimeMinute);
|
||||||
sunsetTime = new Date(sunset.setTime(stopTime.getTime() + 1 * 86400000));
|
} else {
|
||||||
|
stopTime = this._times.dusk;
|
||||||
|
}
|
||||||
|
|
||||||
|
const startColorTemp = this._config.startColorTemp ? this._config.startColorTemp : 4000;
|
||||||
|
const stopColorTemp = this._config.stopColorTemp ? this._config.stopColorTemp : 1900;
|
||||||
|
const sunsetColorTemp = this._config.sunsetColorTemp ? this._config.sunsetColorTemp : 3000;
|
||||||
|
|
||||||
|
let percentageComplete = 0;
|
||||||
|
let newTemp = 0;
|
||||||
|
|
||||||
|
//Adjust for next day times
|
||||||
|
if (stopTime <= startTime) {
|
||||||
|
//Stop time does not happen in the same day as start time
|
||||||
|
if (startTime < now) {
|
||||||
|
//stop time is tomorrow
|
||||||
|
stopTime.setTime(stopTime.getTime() + 1 * 86400000);
|
||||||
|
}
|
||||||
|
} else if (now < startTime) {
|
||||||
|
//Stop time was yesterday since the new start time is not reached
|
||||||
|
stopTime.setTime(stopTime.getTime() - 1 * 86400000);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((startTime < now) && (now < sunset)) {
|
||||||
|
//Before sunset; calculate temp based on TOD
|
||||||
|
const tempRange = Math.abs(startColorTemp - stopColorTemp);
|
||||||
|
const dayLength = (sunset.getTime() - startTime.getTime()) / 1000;
|
||||||
|
const secondsFromStart = (now.getTime() - startTime.getTime()) / 1000;
|
||||||
|
percentageComplete = secondsFromStart / dayLength;
|
||||||
|
const tempOffset = tempRange * percentageComplete;
|
||||||
|
|
||||||
|
if (startColorTemp > sunsetColorTemp) {
|
||||||
|
newTemp = startColorTemp - tempOffset;
|
||||||
} else {
|
} else {
|
||||||
sunsetTime = sunset;
|
newTemp = startColorTemp + tempOffset;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//After sunset; calculate temp based on TOD
|
||||||
|
if (now < stopTime) {
|
||||||
|
let sunsetTime;
|
||||||
|
if ((stopTime < startTime) && stopTime.getDay() == sunset.getDay()) {
|
||||||
|
sunsetTime = new Date(sunset.setTime(stopTime.getTime() + 1 * 86400000));
|
||||||
|
} else {
|
||||||
|
sunsetTime = sunset;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nightLength = (stopTime.getTime() - sunsetTime.getTime()) / 1000;
|
||||||
|
const secondsFromSunset = (now.getTime() - sunsetTime.getTime()) / 100;
|
||||||
|
percentageComplete = secondsFromSunset / nightLength;
|
||||||
|
} else {
|
||||||
|
percentageComplete = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const nightLength = (stopTime.getTime() - sunsetTime.getTime()) / 1000;
|
const tempRange = Math.abs(sunsetColorTemp - stopColorTemp);
|
||||||
const secondsFromSunset = (now.getTime() - sunsetTime.getTime()) / 100;
|
const tempOffset = tempRange * percentageComplete;
|
||||||
percentageComplete = secondsFromSunset / nightLength;
|
|
||||||
} else {
|
if (startColorTemp > sunsetColorTemp) {
|
||||||
percentageComplete = 1;
|
newTemp = startColorTemp - tempOffset;
|
||||||
|
} else {
|
||||||
|
newTemp = startColorTemp + tempOffset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const tempRange = Math.abs(sunsetColorTemp - stopColorTemp);
|
//Set lights
|
||||||
const tempOffset = tempRange * percentageComplete;
|
const rgb = this.colorTempToRgb(newTemp);
|
||||||
|
if (rgb) {
|
||||||
if (startColorTemp > sunsetColorTemp) {
|
const lightState = new LightState();
|
||||||
newTemp = startColorTemp - tempOffset;
|
lightState
|
||||||
} else {
|
.transitionInMillis(this._config.transition ? this._config.transition : 5000)
|
||||||
newTemp = startColorTemp + tempOffset;
|
.rgb(rgb.red ? rgb.red : 0, rgb.green ? rgb.green : 0, rgb.blue ? rgb.blue : 0);
|
||||||
|
await this.setLights(lightState)
|
||||||
|
this._log(`Adjusting light temp to ${newTemp}, ${JSON.stringify(rgb)}`)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//Set lights
|
await Sleep(this._config.delay ? this._config.delay : 60000);
|
||||||
const rgb = this.colorTempToRgb(newTemp);
|
|
||||||
if (rgb) {
|
|
||||||
const lightState = new LightState();
|
|
||||||
lightState
|
|
||||||
.transitionInMillis(this._config.transition ? this._config.transition : 5000)
|
|
||||||
.rgb(rgb.red, rgb.green, rgb.blue);
|
|
||||||
await this.setLights(lightState)
|
|
||||||
this._log(`Adjusting light temp to ${newTemp}, ${JSON.stringify(rgb)}`)
|
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user