Skip to content

Commit

Permalink
Simplified operating lights
Browse files Browse the repository at this point in the history
  • Loading branch information
AlCalzone committed Nov 4, 2017
1 parent 225cd31 commit def1fbc
Show file tree
Hide file tree
Showing 12 changed files with 398 additions and 7 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Library to talk to IKEA Trådfri Gateways without external binaries

#### 0.4.0 (2017-11-04)
* (AlCalzone) Reworked the observe api so it resides on TradfriClient now
* (AlCalzone) Simplified operating lights

#### 0.3.0 (2017-11-02)
* (AlCalzone) Changed authentication procedure to comply with IKEA's request
Expand Down
7 changes: 7 additions & 0 deletions build/lib/accessory.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { TradfriClient } from "../tradfri-client";
import { DeviceInfo } from "./deviceInfo";
import { IPSODevice } from "./ipsoDevice";
import { Light } from "./light";
Expand All @@ -18,4 +19,10 @@ export declare class Accessory extends IPSODevice {
sensorList: Sensor[];
switchList: IPSODevice[];
otaUpdateState: number;
/**
* Link this object to a TradfriClient for a simplified API.
* INTERNAL USE ONLY!
* @param client The client instance to link this object to
*/
link(client: TradfriClient): this;
}
21 changes: 21 additions & 0 deletions build/lib/accessory.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,27 @@ class Accessory extends ipsoDevice_1.IPSODevice {
this.lastSeen = 0;
this.otaUpdateState = 0; // boolean?
}
/**
* Link this object to a TradfriClient for a simplified API.
* INTERNAL USE ONLY!
* @param client The client instance to link this object to
*/
link(client) {
super.link(client);
for (const light of this.lightList) {
light.link(client);
}
for (const plug of this.plugList) {
plug.link(client);
}
for (const sensor of this.sensorList) {
sensor.link(client);
}
for (const swtch of this.switchList) {
swtch.link(client);
}
return this;
}
}
__decorate([
ipsoObject_1.ipsoKey("5750"),
Expand Down
8 changes: 8 additions & 0 deletions build/lib/ipsoObject.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { TradfriClient } from "../tradfri-client";
import { DictionaryLike } from "./object-polyfill";
export declare type PropertyTransform = (value: any, parent?: IPSOObject) => any;
export declare type RequiredPredicate = (me: IPSOObject, reference: IPSOObject) => boolean;
Expand Down Expand Up @@ -54,4 +55,11 @@ export declare class IPSOObject {
* @param set Custom setter trap (optional). This is called after mandatory traps are in place and before default behavior
*/
createProxy(get?: (me: this, key: PropertyKey) => any, set?: (me: this, key: PropertyKey, value, receiver) => boolean): this;
protected client: TradfriClient;
/**
* Link this object to a TradfriClient for a simplified API.
* INTERNAL USE ONLY!
* @param client The client instance to link this object to
*/
link(client: TradfriClient): this;
}
14 changes: 14 additions & 0 deletions build/lib/ipsoObject.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
const tradfri_client_1 = require("../tradfri-client");
const logger_1 = require("./logger");
const object_polyfill_1 = require("./object-polyfill");
// ===========================================================
Expand Down Expand Up @@ -469,9 +470,22 @@ class IPSOObject {
},
});
}
/**
* Link this object to a TradfriClient for a simplified API.
* INTERNAL USE ONLY!
* @param client The client instance to link this object to
*/
link(client) {
this.client = client;
return this;
}
}
__decorate([
exports.doNotSerialize,
__metadata("design:type", Boolean)
], IPSOObject.prototype, "isProxy", void 0);
__decorate([
exports.doNotSerialize,
__metadata("design:type", tradfri_client_1.TradfriClient)
], IPSOObject.prototype, "client", void 0);
exports.IPSOObject = IPSOObject;
40 changes: 40 additions & 0 deletions build/lib/light.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export declare type LightOperation = Partial<Pick<Light, "onOff" | "dimmer" | "c
export declare class Light extends IPSODevice {
constructor(accessory?: Accessory);
private _modelName;
private _accessory;
color: string;
hue: number;
saturation: number;
Expand Down Expand Up @@ -35,5 +36,44 @@ export declare class Light extends IPSODevice {
* Creates a proxy which redirects the properties to the correct internal one
*/
createProxy(): this;
/**
* Ensures this instance is linked to a tradfri client and an accessory
* @throws Throws an error if it isn't
*/
private ensureLink();
/** Turn this lightbulb on */
turnOn(): Promise<void>;
/** Turn this lightbulb off */
turnOff(): Promise<void>;
/** Toggles this lightbulb on or off */
toggle(value?: boolean): Promise<void>;
private operateLight(operation, transitionTime?);
/**
* Changes this lightbulb's brightness
* @returns true if a request was sent, false otherwise
*/
setBrightness(value: number, transitionTime?: number): Promise<boolean>;
/**
* Changes this lightbulb's color
* @param value The target color as a 6-digit hex string
* @returns true if a request was sent, false otherwise
*/
setColor(value: string, transitionTime?: number): Promise<boolean>;
/**
* Changes this lightbulb's color temperature
* @param value The target color temperature in the range 0% (cold) to 100% (warm)
* @returns true if a request was sent, false otherwise
*/
setColorTemperature(value: number, transitionTime?: number): Promise<boolean>;
/**
* Changes this lightbulb's color hue
* @returns true if a request was sent, false otherwise
*/
setHue(value: number, transitionTime?: number): Promise<boolean>;
/**
* Changes this lightbulb's color saturation
* @returns true if a request was sent, false otherwise
*/
setSaturation(value: number, transitionTime?: number): Promise<boolean>;
}
export declare type Spectrum = "none" | "white" | "rgb";
144 changes: 144 additions & 0 deletions build/lib/light.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,21 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const tradfri_client_1 = require("../tradfri-client");
const accessory_1 = require("./accessory");
const conversions_1 = require("./conversions");
const ipsoDevice_1 = require("./ipsoDevice");
const ipsoObject_1 = require("./ipsoObject");
const math_1 = require("./math");
const predefined_colors_1 = require("./predefined-colors");
class Light extends ipsoDevice_1.IPSODevice {
constructor(accessory) {
Expand All @@ -22,6 +33,7 @@ class Light extends ipsoDevice_1.IPSODevice {
* Returns the supported color spectrum of the lightbulb
*/
this._spectrum = null;
this._accessory = accessory;
// get the model number to detect features
if (accessory != null &&
accessory.deviceInfo != null &&
Expand Down Expand Up @@ -81,7 +93,139 @@ class Light extends ipsoDevice_1.IPSODevice {
return this;
}
}
// =================================
// Simplified API access
/**
* Ensures this instance is linked to a tradfri client and an accessory
* @throws Throws an error if it isn't
*/
ensureLink() {
if (!(this.client instanceof tradfri_client_1.TradfriClient)) {
throw new Error("Cannot use the simplified API on devices which aren't linked to a client instance.");
}
if (!(this._accessory instanceof accessory_1.Accessory)) {
throw new Error("Cannot use the simplified API on lightbulbs which aren't linked to an Accessory instance.");
}
}
/** Turn this lightbulb on */
turnOn() {
return __awaiter(this, void 0, void 0, function* () {
this.ensureLink();
yield this.client.operateLight(this._accessory, {
onOff: true,
});
});
}
/** Turn this lightbulb off */
turnOff() {
return __awaiter(this, void 0, void 0, function* () {
this.ensureLink();
yield this.client.operateLight(this._accessory, {
onOff: false,
});
});
}
/** Toggles this lightbulb on or off */
toggle(value = !this.onOff) {
return __awaiter(this, void 0, void 0, function* () {
this.ensureLink();
yield this.client.operateLight(this._accessory, {
onOff: value,
});
});
}
operateLight(operation, transitionTime) {
return __awaiter(this, void 0, void 0, function* () {
if (transitionTime != null) {
transitionTime = Math.max(0, transitionTime);
operation.transitionTime = transitionTime;
}
return this.client.operateLight(this._accessory, operation);
});
}
/**
* Changes this lightbulb's brightness
* @returns true if a request was sent, false otherwise
*/
setBrightness(value, transitionTime) {
return __awaiter(this, void 0, void 0, function* () {
this.ensureLink();
value = math_1.clamp(value, 0, 100);
return this.operateLight({
dimmer: value,
}, transitionTime);
});
}
/**
* Changes this lightbulb's color
* @param value The target color as a 6-digit hex string
* @returns true if a request was sent, false otherwise
*/
setColor(value, transitionTime) {
return __awaiter(this, void 0, void 0, function* () {
if (this.spectrum === "rgb")
throw new Error("setColor is only available for RGB lightbulbs");
this.ensureLink();
return this.operateLight({
color: value,
}, transitionTime);
});
}
/**
* Changes this lightbulb's color temperature
* @param value The target color temperature in the range 0% (cold) to 100% (warm)
* @returns true if a request was sent, false otherwise
*/
setColorTemperature(value, transitionTime) {
return __awaiter(this, void 0, void 0, function* () {
if (this.spectrum === "white")
throw new Error("setColorTemperature is only available for white spectrum lightbulbs");
this.ensureLink();
value = math_1.clamp(value, 0, 100);
return this.operateLight({
colorTemperature: value,
}, transitionTime);
});
}
/**
* Changes this lightbulb's color hue
* @returns true if a request was sent, false otherwise
*/
setHue(value, transitionTime) {
return __awaiter(this, void 0, void 0, function* () {
if (this.spectrum === "rgb")
throw new Error("setHue is only available for RGB lightbulbs");
this.ensureLink();
value = math_1.clamp(value, 0, 360);
return this.operateLight({
hue: value,
}, transitionTime);
});
}
/**
* Changes this lightbulb's color saturation
* @returns true if a request was sent, false otherwise
*/
setSaturation(value, transitionTime) {
return __awaiter(this, void 0, void 0, function* () {
if (this.spectrum === "rgb")
throw new Error("setSaturation is only available for RGB lightbulbs");
this.ensureLink();
value = math_1.clamp(value, 0, 100);
return this.operateLight({
saturation: value,
}, transitionTime);
});
}
}
__decorate([
ipsoObject_1.doNotSerialize,
__metadata("design:type", String)
], Light.prototype, "_modelName", void 0);
__decorate([
ipsoObject_1.doNotSerialize,
__metadata("design:type", accessory_1.Accessory)
], Light.prototype, "_accessory", void 0);
__decorate([
ipsoObject_1.ipsoKey("5706"),
ipsoObject_1.doNotSerialize // this is done through colorX / colorY
Expand Down
6 changes: 3 additions & 3 deletions build/tradfri-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ class TradfriClient extends events_1.EventEmitter {
// store a clone, so we don't have to care what the calling library does
this.devices[instanceId] = accessory.clone();
// and notify all listeners about the update
this.emit("device updated", accessory);
this.emit("device updated", accessory.link(this));
}
/** Sets up an observer for all groups */
observeGroupsAndScenes() {
Expand Down Expand Up @@ -294,7 +294,7 @@ class TradfriClient extends events_1.EventEmitter {
// store a clone, so we don't have to care what the calling library does
groupInfo.group = group.clone();
// notify all listeners about the update
this.emit("group updated", group);
this.emit("group updated", group.link(this));
// load scene information
this.observeResource(`${endpoints_1.endpoints.scenes}/${instanceId}`, (resp) => this.observeScenes_callback(instanceId, resp));
});
Expand Down Expand Up @@ -353,7 +353,7 @@ class TradfriClient extends events_1.EventEmitter {
// store a clone, so we don't have to care what the calling library does
this.groups[groupId].scenes[instanceId] = scene.clone();
// and notify all listeners about the update
this.emit("scene updated", groupId, scene);
this.emit("scene updated", groupId, scene.link(this));
}
/**
* Pings the gateway to check if it is alive
Expand Down
23 changes: 23 additions & 0 deletions src/lib/accessory.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { TradfriClient } from "../tradfri-client";
import { DeviceInfo } from "./deviceInfo";
import { IPSODevice } from "./ipsoDevice";
import { deserializeWith, ipsoKey, IPSOObject, PropertyTransform, required, serializeWith } from "./ipsoObject";
Expand Down Expand Up @@ -47,4 +48,26 @@ export class Accessory extends IPSODevice {
@ipsoKey("9054")
public otaUpdateState: number = 0; // boolean?

/**
* Link this object to a TradfriClient for a simplified API.
* INTERNAL USE ONLY!
* @param client The client instance to link this object to
*/
public link(client: TradfriClient): this {
super.link(client);
for (const light of this.lightList) {
light.link(client);
}
for (const plug of this.plugList) {
plug.link(client);
}
for (const sensor of this.sensorList) {
sensor.link(client);
}
for (const swtch of this.switchList) {
swtch.link(client);
}
return this;
}

}
Loading

0 comments on commit def1fbc

Please sign in to comment.