Working with all lights

This commit is contained in:
watsonb8 2020-04-13 20:50:07 -04:00
parent eacd56afa5
commit a43ecd2700

View File

@ -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;
} }
} }