Skip to content

Commit

Permalink
Merge pull request #21 from AlCalzone/raw-values
Browse files Browse the repository at this point in the history
Support using raw CoAP values
  • Loading branch information
AlCalzone authored Jan 28, 2018
2 parents 984ce4f + 6e1028f commit 68241c5
Show file tree
Hide file tree
Showing 27 changed files with 380 additions and 299 deletions.
32 changes: 22 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,19 +85,28 @@ const TradfriClient = tradfriLib.TradfriClient;
// or with the new import syntax
import { TradfriClient /*, more imports */ } from "node-tradfri-client";

const tradfri = new TradfriClient(
hostname: string,
[customLogger: LoggerFunction]
);
// one of the following
const tradfri = new TradfriClient(hostname: string);
const tradfri = new TradfriClient(hostname: string, customLogger: LoggerFunction);
const tradfri = new TradfriClient(hostname: string, options: TradfriOptions);
```
By providing a custom logger function to the constructor, all diagnostic output will be sent to that function. By default, the `debug` module is used instead. The logger function has the following signature:
As the 2nd parameter, you can provide a custom logger function or some options. By providing a custom logger function to the constructor, all diagnostic output will be sent to that function. By default, the `debug` module is used instead. The logger function has the following signature:
```TS
type LoggerFunction = (
message: string,
[severity: "info" | "warn" | "debug" | "error" | "silly"]
) => void;
```

The options object looks as follows:
```TS
interface TradfriOptions {
customLogger?: LoggerFunction,
useRawCoAPValues?: boolean,
}
```
The custom logger function is used as above. By setting `useRawCoAPValues` to true, you can instruct `TradfriClient` to use raw CoAP values instead of the simplified scales used internally. See below for a detailed description how the scales change.

The following code samples use the new `async/await` syntax which is available through TypeScript/Babel or in ES7. If that is no option for you, you can also consume the library by using promises:
```TS
try {
Expand Down Expand Up @@ -328,7 +337,7 @@ The properties available on an `Accessory` are:

### `Light`
A light represents a single lightbulb and has several properties describing its state. The supported properties depend on the spectrum of the lightbulb. All of them support the most basic properties:
* `dimmer: number` - The brightness in percent [0..100%]
* `dimmer: number` - The brightness in percent [0..100%]. _Note:_ When using raw values, this range is [0..254].
* `onOff: boolean` - If the lightbulb is on (`true`) or off (`false`)
* `transitionTime: number` - The duration of state changes in seconds. Default 0.5s, not supported for on/off.

Expand All @@ -338,12 +347,12 @@ as well as a few readonly properties:
* `spectrum: "none" | "white" | "rgb"` - The supported color spectrum of the lightbulb.

White spectrum lightbulbs also support
* `colorTemperature: number` - The color temperature in percent, where 0% equals cold white and 100% equals warm white.
* `colorTemperature: number` - The color temperature in percent, where 0% equals cold white and 100% equals warm white. _Note:_ When using raw values, this range is 250 (cold) to 454 (warm).

RGB lightbulbs have the following properties:
* `color: string` - The 6 digit hex number representing the lightbulb's color. Don't use any prefixes like "#", only the hex number itself!
* `hue: number` - The color's hue [0..360°]
* `saturation: number` - The color's saturation [0..100%]
* `hue: number` - The color's hue [0..360°]. _Note:_ When using raw values, this range is [0..65279].
* `saturation: number` - The color's saturation [0..100%]. _Note:_ When using raw values, this range is [0..65279].

The additional properties are either for internal use (`colorX`/`colorY`) or not supported by the gateway. So don't use them!

Expand Down Expand Up @@ -377,7 +386,7 @@ or a subset thereof.
### `Group`
A group contains several devices, usually a remote control or dimmer and some lightbulbs. To control the group's lightbulbs, use the following properties:
* `onOff: boolean` - Turn the group's lightbulbs on (`true`) or off (`false`)
* `dimmer: number` - Set the brightness of the group's lightbulbs in percent [0..100%]
* `dimmer: number` - Set the brightness of the group's lightbulbs in percent [0..100%]. _Note:_ When using raw values, this range is [0..254].
* `transitionTime: number` - The duration of state changes in seconds. Not supported for on/off.
In contrast to controlling lightbulbs, the default transition time for groups is 0s (no transition).

Expand Down Expand Up @@ -426,6 +435,9 @@ A DeviceInfo object contains general information about a device. It has the foll

## Changelog

#### 0.7.0 (2018-01-28)
* (AlCalzone) Support using raw CoAP values instead of the simplified scales for many properties.

#### 0.6.0 (2018-01-13)
* (AlCalzone) Use the `colorTemperature` CoAP property directly instead of `colorX/Y`

Expand Down
7 changes: 0 additions & 7 deletions build/lib/accessory.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { DeviceInfo } from "./deviceInfo";
import { IPSODevice } from "./ipsoDevice";
import { Light } from "./light";
import { OperationProvider } from "./operation-provider";
import { Plug } from "./plug";
import { Sensor } from "./sensor";
export declare enum AccessoryTypes {
Expand All @@ -19,10 +18,4 @@ 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: OperationProvider): this;
}
12 changes: 6 additions & 6 deletions build/lib/accessory.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ class Accessory extends ipsoDevice_1.IPSODevice {
}
/**
* Link this object to a TradfriClient for a simplified API.
* INTERNAL USE ONLY!
* @param client The client instance to link this object to
* @internal
*/
link(client) {
super.link(client);
Expand Down Expand Up @@ -68,7 +68,7 @@ __decorate([
], Accessory.prototype, "type", void 0);
__decorate([
ipsoObject_1.ipsoKey("3"),
ipsoObject_1.deserializeWith(obj => new deviceInfo_1.DeviceInfo().parse(obj)),
ipsoObject_1.deserializeWith((obj, me) => new deviceInfo_1.DeviceInfo(me.options).parse(obj)),
__metadata("design:type", deviceInfo_1.DeviceInfo)
], Accessory.prototype, "deviceInfo", void 0);
__decorate([
Expand All @@ -81,22 +81,22 @@ __decorate([
], Accessory.prototype, "lastSeen", void 0);
__decorate([
ipsoObject_1.ipsoKey("3311"),
ipsoObject_1.deserializeWith((obj, me) => new light_1.Light(me).parse(obj)),
ipsoObject_1.deserializeWith((obj, me) => new light_1.Light(me, me.options).parse(obj)),
__metadata("design:type", Array)
], Accessory.prototype, "lightList", void 0);
__decorate([
ipsoObject_1.ipsoKey("3312"),
ipsoObject_1.deserializeWith(obj => new plug_1.Plug().parse(obj)),
ipsoObject_1.deserializeWith((obj, me) => new plug_1.Plug(me.options).parse(obj)),
__metadata("design:type", Array)
], Accessory.prototype, "plugList", void 0);
__decorate([
ipsoObject_1.ipsoKey("3300"),
ipsoObject_1.deserializeWith(obj => new sensor_1.Sensor().parse(obj)),
ipsoObject_1.deserializeWith((obj, me) => new sensor_1.Sensor(me.options).parse(obj)),
__metadata("design:type", Array)
], Accessory.prototype, "sensorList", void 0);
__decorate([
ipsoObject_1.ipsoKey("15009"),
ipsoObject_1.deserializeWith(obj => new ipsoDevice_1.IPSODevice().parse(obj)),
ipsoObject_1.deserializeWith((obj, me) => new ipsoDevice_1.IPSODevice(me.options).parse(obj)),
__metadata("design:type", Array)
], Accessory.prototype, "switchList", void 0);
__decorate([
Expand Down
22 changes: 11 additions & 11 deletions build/lib/conversions.d.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { PropertyTransform } from "./ipsoObject";
import { PropertyTransformKernel } from "./ipsoObject";
export declare const serializers: {
transitionTime: PropertyTransform;
hue: PropertyTransform;
saturation: PropertyTransform;
brightness: PropertyTransform;
colorTemperature: PropertyTransform;
transitionTime: PropertyTransformKernel;
hue: PropertyTransformKernel;
saturation: PropertyTransformKernel;
brightness: PropertyTransformKernel;
colorTemperature: PropertyTransformKernel;
};
export declare const deserializers: {
transitionTime: PropertyTransform;
hue: PropertyTransform;
saturation: PropertyTransform;
brightness: PropertyTransform;
colorTemperature: PropertyTransform;
transitionTime: PropertyTransformKernel;
hue: PropertyTransformKernel;
saturation: PropertyTransformKernel;
brightness: PropertyTransformKernel;
colorTemperature: PropertyTransformKernel;
};
export declare const conversions: {
rgbFromCIExyY: (x: number, y: number, Y?: number) => {
Expand Down
3 changes: 1 addition & 2 deletions build/lib/group.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { IPSODevice } from "./ipsoDevice";
import { DictionaryLike } from "./object-polyfill";
import { Scene } from "./scene";
export interface GroupInfo {
group: Group;
scenes: DictionaryLike<Scene>;
scenes: Record<string, Scene>;
}
export declare class Group extends IPSODevice {
onOff: boolean;
Expand Down
6 changes: 3 additions & 3 deletions build/lib/group.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ __decorate([
__decorate([
ipsoObject_1.ipsoKey("9018"),
ipsoObject_1.deserializeWith(obj => parseAccessoryLink(obj)),
ipsoObject_1.serializeWith(ids => toAccessoryLink(ids), false),
ipsoObject_1.serializeWith(ids => toAccessoryLink(ids), { splitArrays: false }),
__metadata("design:type", Array)
], Group.prototype, "deviceIDs", void 0);
__decorate([
Expand All @@ -122,8 +122,8 @@ __decorate([
// all other properties don't support the transition time
,
ipsoObject_1.required((me, ref) => ref != null && me.dimmer !== ref.dimmer),
ipsoObject_1.serializeWith(conversions_1.serializers.transitionTime),
ipsoObject_1.deserializeWith(conversions_1.deserializers.transitionTime),
ipsoObject_1.serializeWith(conversions_1.serializers.transitionTime, { neverSkip: true }),
ipsoObject_1.deserializeWith(conversions_1.deserializers.transitionTime, { neverSkip: true }),
__metadata("design:type", Number)
], Group.prototype, "transitionTime", void 0);
exports.Group = Group;
Expand Down
44 changes: 30 additions & 14 deletions build/lib/ipsoObject.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { DictionaryLike } from "./object-polyfill";
import { OperationProvider } from "./operation-provider";
export declare type PropertyTransform = (value: any, parent?: IPSOObject) => any;
export declare type PropertyTransformKernel = (value: any, parent?: IPSOObject) => any;
export interface PropertyTransform extends PropertyTransformKernel {
/** If this transform is not supposed to be skipped ever */
neverSkip: boolean;
/** If this transform requires arrays to be split */
splitArrays: boolean;
}
export declare type RequiredPredicate = (me: IPSOObject, reference: IPSOObject) => boolean;
/**
* Defines the ipso key neccessary to serialize a property to a CoAP object
Expand All @@ -13,31 +18,48 @@ export declare const required: (predicate?: boolean | RequiredPredicate) => Prop
/**
* Defines the required transformations to serialize a property to a CoAP object
* @param transform: The transformation to apply during serialization
* @param splitArrays: Whether the serializer expects arrays to be split up in advance
* @param options: Some options regarding the behavior of the property transform
*/
export declare const serializeWith: (transform: PropertyTransform, splitArrays?: boolean) => PropertyDecorator;
export declare function serializeWith(kernel: PropertyTransformKernel, options?: {
splitArrays?: boolean;
neverSkip?: boolean;
}): PropertyDecorator;
/**
* Defines the required transformations to deserialize a property from a CoAP object
* @param transform: The transformation to apply during deserialization
* @param splitArrays: Whether the deserializer expects arrays to be split up in advance
*/
export declare const deserializeWith: (transforms: PropertyTransform | PropertyTransform[], splitArrays?: boolean) => PropertyDecorator;
export declare function deserializeWith(kernel: PropertyTransformKernel, options?: {
splitArrays?: boolean;
neverSkip?: boolean;
}): PropertyDecorator;
/**
* Defines that a property will not be serialized
*/
export declare const doNotSerialize: (target: object, property: string | symbol) => void;
/**
* Provides a set of options regarding IPSO objects and serialization
*/
export interface IPSOOptions {
/**
* Determines if basic serializers (i.e. for simple values) should be skipped
* This is used to support raw CoAP values instead of the simplified scales
*/
skipBasicSerializers?: boolean;
}
export declare class IPSOObject {
constructor(options?: IPSOOptions);
/**
* Reads this instance's properties from the given object
*/
parse(obj: DictionaryLike<any>): this;
private parseValue(propKey, value, deserializers?, requiresArraySplitting?);
parse(obj: Record<string, any>): this;
private parseValue(propKey, value, transform?, requiresArraySplitting?);
/**
* Overrides this object's properties with those from another partial one
*/
merge(obj: Partial<this>): this;
/** serializes this object in order to transfer it via COAP */
serialize(reference?: any): DictionaryLike<any>;
serialize(reference?: any): Record<string, any>;
/**
* Deeply clones an IPSO Object
*/
Expand All @@ -54,10 +76,4 @@ export declare class IPSOObject {
*/
createProxy(get?: (me: this, key: PropertyKey) => any, set?: (me: this, key: PropertyKey, value, receiver) => boolean): this;
protected client: OperationProvider;
/**
* 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: OperationProvider): this;
}
Loading

0 comments on commit 68241c5

Please sign in to comment.