homebridge-nanoleaf-multi 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitlab-ci.yml +24 -0
- package/README.md +9 -0
- package/dist/Device.d.ts +17 -0
- package/dist/Effect.d.ts +22 -0
- package/dist/RandomEffect.d.ts +23 -0
- package/dist/SolidEffect.d.ts +22 -0
- package/dist/WaveEffect.d.ts +23 -0
- package/dist/Zone.d.ts +26 -0
- package/dist/accessories/DynamicEffectColorAccessory.d.ts +5 -0
- package/dist/accessories/ZoneAccessory.d.ts +13 -0
- package/dist/accessories/index.d.ts +3 -0
- package/dist/constants.d.ts +9 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.LICENSE.txt +17 -0
- package/dist/platformFactory.d.ts +12 -0
- package/dist/types/Context.d.ts +9 -0
- package/dist/types/PlatformConfiguration.d.ts +6 -0
- package/dist/types/devices/DeviceConfiguration.d.ts +7 -0
- package/dist/types/devices/ZoneConfiguration.d.ts +8 -0
- package/dist/types/devices/index.d.ts +3 -0
- package/dist/types/effects/ConstantEffectColorConfiguration.d.ts +4 -0
- package/dist/types/effects/DynamicEffectColorConfiguration.d.ts +6 -0
- package/dist/types/effects/EffectColorConfiguration.d.ts +5 -0
- package/dist/types/effects/EffectColorConfigurationBase.d.ts +3 -0
- package/dist/types/effects/EffectColorType.d.ts +6 -0
- package/dist/types/effects/EffectConfiguration.d.ts +5 -0
- package/dist/types/effects/EffectConfigurationBase.d.ts +8 -0
- package/dist/types/effects/EffectType.d.ts +6 -0
- package/dist/types/effects/RemoteEffectColorConfiguration.d.ts +4 -0
- package/dist/types/effects/index.d.ts +14 -0
- package/dist/types/effects/native/NativeDirection.d.ts +7 -0
- package/dist/types/effects/native/NativeEffect.d.ts +13 -0
- package/dist/types/effects/native/NativeEffectColor.d.ts +6 -0
- package/dist/types/effects/native/NativeEffectOption.d.ts +18 -0
- package/dist/types/effects/native/NativeEffectType.d.ts +9 -0
- package/dist/types/effects/native/index.d.ts +6 -0
- package/dist/types/effects/random-effect/RandomEffectConfiguration.d.ts +9 -0
- package/dist/types/effects/random-effect/index.d.ts +2 -0
- package/dist/types/effects/solid-effect/SolidEffectColorConfiguration.d.ts +4 -0
- package/dist/types/effects/solid-effect/SolidEffectConfiguration.d.ts +7 -0
- package/dist/types/effects/solid-effect/index.d.ts +3 -0
- package/dist/types/effects/wave-effect/WaveEffectConfiguration.d.ts +11 -0
- package/dist/types/effects/wave-effect/index.d.ts +2 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/utilities/HomebridgeLogAppender.d.ts +7 -0
- package/dist/utilities/colorToNanoleafColor.d.ts +4 -0
- package/dist/utilities/index.d.ts +4 -0
- package/dist/utilities/nativeEffectTypeToPluginUuid.d.ts +3 -0
- package/package.json +52 -0
- package/src/Device.ts +73 -0
- package/src/Effect.ts +80 -0
- package/src/RandomEffect.ts +82 -0
- package/src/SolidEffect.ts +38 -0
- package/src/WaveEffect.ts +95 -0
- package/src/Zone.ts +151 -0
- package/src/accessories/DynamicEffectColorAccessory.ts +19 -0
- package/src/accessories/ZoneAccessory.ts +46 -0
- package/src/accessories/index.ts +4 -0
- package/src/constants.ts +32 -0
- package/src/index.ts +11 -0
- package/src/platformFactory.ts +88 -0
- package/src/types/Context.ts +10 -0
- package/src/types/PlatformConfiguration.ts +7 -0
- package/src/types/devices/DeviceConfiguration.ts +7 -0
- package/src/types/devices/ZoneConfiguration.ts +9 -0
- package/src/types/devices/index.ts +4 -0
- package/src/types/effects/ConstantEffectColorConfiguration.ts +9 -0
- package/src/types/effects/DynamicEffectColorConfiguration.ts +12 -0
- package/src/types/effects/EffectColorConfiguration.ts +10 -0
- package/src/types/effects/EffectColorConfigurationBase.ts +3 -0
- package/src/types/effects/EffectColorType.ts +9 -0
- package/src/types/effects/EffectConfiguration.ts +10 -0
- package/src/types/effects/EffectConfigurationBase.ts +9 -0
- package/src/types/effects/EffectType.ts +7 -0
- package/src/types/effects/RemoteEffectColorConfiguration.ts +9 -0
- package/src/types/effects/index.ts +25 -0
- package/src/types/effects/native/NativeDirection.ts +8 -0
- package/src/types/effects/native/NativeEffect.ts +14 -0
- package/src/types/effects/native/NativeEffectColor.ts +6 -0
- package/src/types/effects/native/NativeEffectOption.ts +25 -0
- package/src/types/effects/native/NativeEffectType.ts +10 -0
- package/src/types/effects/native/index.ts +13 -0
- package/src/types/effects/random-effect/RandomEffectConfiguration.ts +11 -0
- package/src/types/effects/random-effect/index.ts +3 -0
- package/src/types/effects/solid-effect/SolidEffectColorConfiguration.ts +8 -0
- package/src/types/effects/solid-effect/SolidEffectConfiguration.ts +9 -0
- package/src/types/effects/solid-effect/index.ts +4 -0
- package/src/types/effects/wave-effect/WaveEffectConfiguration.ts +13 -0
- package/src/types/effects/wave-effect/index.ts +3 -0
- package/src/types/index.ts +6 -0
- package/src/utilities/HomebridgeLogAppender.ts +15 -0
- package/src/utilities/colorToNanoleafColor.ts +14 -0
- package/src/utilities/index.ts +9 -0
- package/src/utilities/nativeEffectTypeToPluginUuid.ts +4 -0
- package/tsconfig.json +21 -0
- package/webpack.config.js +42 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/*! ReadWriteLock - v5.0.0 - 2015-01-16
|
|
2
|
+
* Author: Alberto La Rocca <a71104@gmail.com> (https://github.com/71104)
|
|
3
|
+
* Released under the MIT license
|
|
4
|
+
* Copyright (c) 2015 Alberto La Rocca */
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @license
|
|
8
|
+
* Lodash <https://lodash.com/>
|
|
9
|
+
* Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
|
|
10
|
+
* Released under MIT license <https://lodash.com/license>
|
|
11
|
+
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
|
12
|
+
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
//! moment.js
|
|
16
|
+
|
|
17
|
+
//! moment.js locale configuration
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { PlatformConfiguration, Context } from './types';
|
|
2
|
+
import Zone from './Zone';
|
|
3
|
+
declare const _default: (homebridge: any) => {
|
|
4
|
+
new (homebridgeLog: any, configuration: PlatformConfiguration): {
|
|
5
|
+
context: Context;
|
|
6
|
+
zones: Map<string, Zone>;
|
|
7
|
+
readonly allEffects: import("./Effect").default<any>[];
|
|
8
|
+
readonly configuration: PlatformConfiguration;
|
|
9
|
+
accessories(callback: any): Promise<void>;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
export default _default;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { PaletteClient } from '@manganese/palette-kit-client';
|
|
2
|
+
import { Palette } from '@manganese/palette-kit-core';
|
|
3
|
+
import SimpleLogger from 'simple-node-logger';
|
|
4
|
+
export default interface Context {
|
|
5
|
+
homebridge: any;
|
|
6
|
+
palette: Palette;
|
|
7
|
+
paletteClient: PaletteClient;
|
|
8
|
+
log: SimpleLogger.Logger;
|
|
9
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import DeviceConfiguration from './DeviceConfiguration';
|
|
2
|
+
import EffectConfiguration from '../effects/EffectConfiguration';
|
|
3
|
+
export default interface ZoneConfiguration {
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
devices: DeviceConfiguration[];
|
|
7
|
+
effects: EffectConfiguration[];
|
|
8
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { ConstantColorConfiguration } from '@manganese/palette-kit-core';
|
|
2
|
+
import EffectColorConfigurationBase from './EffectColorConfigurationBase';
|
|
3
|
+
type ConstantEffectColorConfiguration<AdditionalConfigurationType = {}> = ConstantColorConfiguration<EffectColorConfigurationBase & AdditionalConfigurationType>;
|
|
4
|
+
export default ConstantEffectColorConfiguration;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { DynamicColorConfiguration } from '@manganese/palette-kit-core';
|
|
2
|
+
import EffectColorConfigurationBase from './EffectColorConfigurationBase';
|
|
3
|
+
type DynamicEffectColorConfiguration<AdditionalConfigurationType = {}> = DynamicColorConfiguration<EffectColorConfigurationBase & AdditionalConfigurationType & {
|
|
4
|
+
name: string;
|
|
5
|
+
}>;
|
|
6
|
+
export default DynamicEffectColorConfiguration;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import ConstantEffectColorConfiguration from './ConstantEffectColorConfiguration';
|
|
2
|
+
import DynamicEffectColorConfiguration from './DynamicEffectColorConfiguration';
|
|
3
|
+
import RemoteEffectColorConfiguration from './RemoteEffectColorConfiguration';
|
|
4
|
+
type EffectColorConfiguration = ConstantEffectColorConfiguration | DynamicEffectColorConfiguration | RemoteEffectColorConfiguration;
|
|
5
|
+
export default EffectColorConfiguration;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { RandomEffectConfiguration } from './random-effect';
|
|
2
|
+
import { SolidEffectConfiguration } from './solid-effect';
|
|
3
|
+
import { WaveEffectConfiguration } from './wave-effect';
|
|
4
|
+
type EffectConfiguration = SolidEffectConfiguration | WaveEffectConfiguration | RandomEffectConfiguration;
|
|
5
|
+
export default EffectConfiguration;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { RemoteColorConfiguration } from '@manganese/palette-kit-client';
|
|
2
|
+
import EffectColorConfigurationBase from './EffectColorConfigurationBase';
|
|
3
|
+
type RemoteEffectColorConfiguration<AdditionalConfigurationType = {}> = RemoteColorConfiguration<EffectColorConfigurationBase & AdditionalConfigurationType>;
|
|
4
|
+
export default RemoteEffectColorConfiguration;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import EffectType from './EffectType';
|
|
2
|
+
import EffectConfiguration from './EffectConfiguration';
|
|
3
|
+
import EffectConfigurationBase from './EffectConfigurationBase';
|
|
4
|
+
import EffectColorType from './EffectColorType';
|
|
5
|
+
import EffectColorConfiguration from './EffectColorConfiguration';
|
|
6
|
+
import EffectColorConfigurationBase from './EffectColorConfigurationBase';
|
|
7
|
+
import ConstantEffectColorConfiguration from './ConstantEffectColorConfiguration';
|
|
8
|
+
import DynamicEffectColorConfiguration from './DynamicEffectColorConfiguration';
|
|
9
|
+
import RemoteEffectColorConfiguration from './RemoteEffectColorConfiguration';
|
|
10
|
+
export * from './native';
|
|
11
|
+
export * from './solid-effect';
|
|
12
|
+
export * from './wave-effect';
|
|
13
|
+
export * from './random-effect';
|
|
14
|
+
export { EffectType, EffectConfiguration, EffectConfigurationBase, EffectColorType, EffectColorConfiguration, EffectColorConfigurationBase, ConstantEffectColorConfiguration, DynamicEffectColorConfiguration, RemoteEffectColorConfiguration, };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import NativeEffectColor from './NativeEffectColor';
|
|
2
|
+
import NativeEffectOption from './NativeEffectOption';
|
|
3
|
+
export default interface NativeEffect {
|
|
4
|
+
version: '2.0';
|
|
5
|
+
animName: string;
|
|
6
|
+
animType: 'plugin';
|
|
7
|
+
colorType: 'HSB';
|
|
8
|
+
palette: NativeEffectColor[];
|
|
9
|
+
pluginType: 'color';
|
|
10
|
+
pluginUuid: string;
|
|
11
|
+
pluginOptions: NativeEffectOption[];
|
|
12
|
+
hasOverlay: false;
|
|
13
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import NativeDirection from './NativeDirection';
|
|
2
|
+
type NativeEffectOption = {
|
|
3
|
+
name: 'delayTime';
|
|
4
|
+
value: number;
|
|
5
|
+
} | {
|
|
6
|
+
name: 'transTime';
|
|
7
|
+
value: number;
|
|
8
|
+
} | {
|
|
9
|
+
name: 'linDirection';
|
|
10
|
+
value: NativeDirection;
|
|
11
|
+
} | {
|
|
12
|
+
name: 'loop';
|
|
13
|
+
value: boolean;
|
|
14
|
+
} | {
|
|
15
|
+
name: 'nColorsPerFrame';
|
|
16
|
+
value: number;
|
|
17
|
+
};
|
|
18
|
+
export default NativeEffectOption;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import NativeDirection from './NativeDirection';
|
|
2
|
+
import NativeEffect from './NativeEffect';
|
|
3
|
+
import NativeEffectType from './NativeEffectType';
|
|
4
|
+
import NativeEffectColor from './NativeEffectColor';
|
|
5
|
+
import NativeEffectOption from './NativeEffectOption';
|
|
6
|
+
export { NativeDirection, NativeEffect, NativeEffectType, NativeEffectColor, NativeEffectOption, };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import EffectConfigurationBase from '../EffectConfigurationBase';
|
|
2
|
+
import EffectType from '../EffectType';
|
|
3
|
+
import EffectColorConfiguration from '../EffectColorConfiguration';
|
|
4
|
+
export default interface RandomEffectConfiguration extends EffectConfigurationBase {
|
|
5
|
+
type: EffectType.Random;
|
|
6
|
+
delayTime: number;
|
|
7
|
+
transitionTime: number;
|
|
8
|
+
colors: EffectColorConfiguration[];
|
|
9
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import DynamicEffectColorConfiguration from '../DynamicEffectColorConfiguration';
|
|
2
|
+
import RemoteEffectColorConfiguration from '../RemoteEffectColorConfiguration';
|
|
3
|
+
type SolidEffectColorConfiguration = DynamicEffectColorConfiguration | RemoteEffectColorConfiguration;
|
|
4
|
+
export default SolidEffectColorConfiguration;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import EffectConfigurationBase from '../EffectConfigurationBase';
|
|
2
|
+
import EffectType from '../EffectType';
|
|
3
|
+
import SolidEffectColorConfiguration from './SolidEffectColorConfiguration';
|
|
4
|
+
export default interface SolidEffectConfiguration extends EffectConfigurationBase {
|
|
5
|
+
type: EffectType.Solid;
|
|
6
|
+
color: SolidEffectColorConfiguration;
|
|
7
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import EffectConfigurationBase from '../EffectConfigurationBase';
|
|
2
|
+
import EffectType from '../EffectType';
|
|
3
|
+
import EffectColorConfiguration from '../EffectColorConfiguration';
|
|
4
|
+
import { NativeDirection } from '../native';
|
|
5
|
+
export default interface WaveEffectConfiguration extends EffectConfigurationBase {
|
|
6
|
+
type: EffectType.Wave;
|
|
7
|
+
direction: NativeDirection;
|
|
8
|
+
transitionTime: number;
|
|
9
|
+
colorSize: number;
|
|
10
|
+
colors: EffectColorConfiguration[];
|
|
11
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AbstractAppender, IEntry, STANDARD_LEVELS } from 'simple-node-logger';
|
|
2
|
+
export default class HomebridgeLogAppender extends AbstractAppender {
|
|
3
|
+
private readonly homebridgeLog;
|
|
4
|
+
constructor(homebridgeLog: (message: string) => void);
|
|
5
|
+
write(entry: IEntry): void;
|
|
6
|
+
setLevel(level: STANDARD_LEVELS): void;
|
|
7
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import HomebridgeLogAppender from './HomebridgeLogAppender';
|
|
2
|
+
import colorToNanoleafColor from './colorToNanoleafColor';
|
|
3
|
+
import nativeEffectTypeToPluginUuid from './nativeEffectTypeToPluginUuid';
|
|
4
|
+
export { HomebridgeLogAppender, colorToNanoleafColor, nativeEffectTypeToPluginUuid, };
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "homebridge-nanoleaf-multi",
|
|
3
|
+
"description": "",
|
|
4
|
+
"homepage": "https://gitlab.com/5131/nanoleaf/homebridge-nanoleaf-multi#readme",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"homebridge-plugin"
|
|
7
|
+
],
|
|
8
|
+
"version": "1.0.0",
|
|
9
|
+
"deprecated": false,
|
|
10
|
+
"author": {
|
|
11
|
+
"name": "Samuel Goodell"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://gitlab.com/5131/nanoleaf/homebridge-nanoleaf-multi/issues"
|
|
15
|
+
},
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+ssh://git@gitlab.com/5131/nanoleaf/homebridge-nanoleaf-multi.git"
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"clean": "rm -rf dist node_modules package-lock.json",
|
|
22
|
+
"build": "webpack",
|
|
23
|
+
"build:development": "NODE_ENV=development webpack",
|
|
24
|
+
"build:production": "NODE_ENV=production webpack"
|
|
25
|
+
},
|
|
26
|
+
"engines": {
|
|
27
|
+
"homebridge": ">=0.4.0",
|
|
28
|
+
"node": ">=8.0.0"
|
|
29
|
+
},
|
|
30
|
+
"main": "dist/index.js",
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@manganese/palette-kit-client": "^1.5",
|
|
33
|
+
"@manganese/palette-kit-core": "^1.5",
|
|
34
|
+
"async-lock": "^1.2.4",
|
|
35
|
+
"axios": "^0.19.2",
|
|
36
|
+
"colors": "^1.4.0",
|
|
37
|
+
"helpers-for-homebridge": "^2.0",
|
|
38
|
+
"nanoleaf-client-multi": "^1.0",
|
|
39
|
+
"rwlock": "^5.0.0",
|
|
40
|
+
"simple-node-logger": "^21.8.12"
|
|
41
|
+
},
|
|
42
|
+
"prettier": "@manganese/prettier-configuration",
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/node": "^18.7.14",
|
|
45
|
+
"@babel/preset-env": "^7.18.10",
|
|
46
|
+
"@manganese/prettier-configuration": "^1.0",
|
|
47
|
+
"babel-loader": "^8.2.5",
|
|
48
|
+
"ts-loader": "^9.3.1",
|
|
49
|
+
"typescript": "^4.8.2",
|
|
50
|
+
"webpack-cli": "^4.10.0"
|
|
51
|
+
}
|
|
52
|
+
}
|
package/src/Device.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { NanoleafClient } from 'nanoleaf-client-multi';
|
|
2
|
+
import ReadWriteLock from 'rwlock';
|
|
3
|
+
|
|
4
|
+
import { Context, DeviceConfiguration, NativeEffect } from './types';
|
|
5
|
+
import { DEFAULT_DEVICE_SIZE } from './constants';
|
|
6
|
+
import Effect from './Effect';
|
|
7
|
+
|
|
8
|
+
export default class Device {
|
|
9
|
+
private initialized = false;
|
|
10
|
+
private nativeDevice: NanoleafClient;
|
|
11
|
+
private lock = new ReadWriteLock();
|
|
12
|
+
|
|
13
|
+
constructor(
|
|
14
|
+
private readonly configuration: DeviceConfiguration,
|
|
15
|
+
private readonly context: Context
|
|
16
|
+
) {}
|
|
17
|
+
|
|
18
|
+
public get name() {
|
|
19
|
+
return this.configuration.name;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public get size() {
|
|
23
|
+
return this.configuration.size || DEFAULT_DEVICE_SIZE;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public async initialize() {
|
|
27
|
+
this.nativeDevice = new NanoleafClient(
|
|
28
|
+
this.configuration.ip,
|
|
29
|
+
this.configuration.token
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const deviceInfo = await this.nativeDevice.getInfo();
|
|
33
|
+
|
|
34
|
+
this.context.log.info(`Initialized <${this.configuration.name}>`);
|
|
35
|
+
this.initialized = true;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
private async withWriteLock(callback: () => Promise<void>) {
|
|
39
|
+
if (!this.initialized) {
|
|
40
|
+
return Promise.reject('Device is not initialized');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return await this.lock.writeLock(async (release) => {
|
|
44
|
+
try {
|
|
45
|
+
await callback();
|
|
46
|
+
} catch (error) {
|
|
47
|
+
this.context.log.debug('Error while holding write lock', error);
|
|
48
|
+
} finally {
|
|
49
|
+
release();
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public async setActive(active: boolean) {
|
|
55
|
+
await this.withWriteLock(async () => {
|
|
56
|
+
await this.nativeDevice.power(active);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public async setActiveEffect(effect: Effect<any>) {
|
|
61
|
+
await this.withWriteLock(async () => {
|
|
62
|
+
const nativeEffect = effect.getNativeEffectForDevice(this);
|
|
63
|
+
|
|
64
|
+
await this.nativeDevice.addEffect(nativeEffect);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public async addNativeEffect(nativeEffect: NativeEffect) {
|
|
69
|
+
await this.withWriteLock(async () => {
|
|
70
|
+
await this.nativeDevice.addEffect(nativeEffect);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
package/src/Effect.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ColorHSV,
|
|
3
|
+
ColorType as CoreColorType,
|
|
4
|
+
} from '@manganese/palette-kit-core';
|
|
5
|
+
import { ClientColorType } from '@manganese/palette-kit-client';
|
|
6
|
+
|
|
7
|
+
import EventEmitter from 'events';
|
|
8
|
+
import {
|
|
9
|
+
Context,
|
|
10
|
+
EffectConfigurationBase,
|
|
11
|
+
NativeEffect,
|
|
12
|
+
ConstantEffectColorConfiguration,
|
|
13
|
+
DynamicEffectColorConfiguration,
|
|
14
|
+
RemoteEffectColorConfiguration,
|
|
15
|
+
} from './types';
|
|
16
|
+
import { DEFAULT_NATIVE_EFFECT_NAME, EFFECT_CHANGE_EVENT } from './constants';
|
|
17
|
+
import Device from './Device';
|
|
18
|
+
|
|
19
|
+
export default abstract class Effect<
|
|
20
|
+
EffectConfigurationType extends EffectConfigurationBase
|
|
21
|
+
> extends EventEmitter {
|
|
22
|
+
protected enabled: boolean;
|
|
23
|
+
|
|
24
|
+
constructor(
|
|
25
|
+
protected readonly configuration: EffectConfigurationType,
|
|
26
|
+
protected readonly context: Context
|
|
27
|
+
) {
|
|
28
|
+
super();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
public async initialize() {}
|
|
32
|
+
|
|
33
|
+
public get id() {
|
|
34
|
+
return this.configuration.id;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public get name() {
|
|
38
|
+
return this.configuration.name;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
protected get nativeEffectBase(): Partial<NativeEffect> {
|
|
42
|
+
return {
|
|
43
|
+
animName: this.configuration.nativeName || DEFAULT_NATIVE_EFFECT_NAME,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
protected handleChange() {
|
|
48
|
+
this.emit(EFFECT_CHANGE_EVENT);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
public abstract getNativeEffectForDevice(device: Device): NativeEffect;
|
|
52
|
+
|
|
53
|
+
public abstract getColors(): Array<
|
|
54
|
+
| ConstantEffectColorConfiguration
|
|
55
|
+
| DynamicEffectColorConfiguration
|
|
56
|
+
| RemoteEffectColorConfiguration
|
|
57
|
+
>;
|
|
58
|
+
|
|
59
|
+
public hasColor(colorId: string) {
|
|
60
|
+
return [...this.getDynamicColors(), ...this.getRemoteColors()].some(
|
|
61
|
+
(colorConfiguration) => {
|
|
62
|
+
return colorConfiguration.id === colorId;
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
public abstract setColor(colorId: string, color: ColorHSV);
|
|
68
|
+
|
|
69
|
+
public getDynamicColors(): DynamicEffectColorConfiguration[] {
|
|
70
|
+
return this.getColors().filter(
|
|
71
|
+
(colorConfiguration) => colorConfiguration.type === CoreColorType.Dynamic
|
|
72
|
+
) as DynamicEffectColorConfiguration[];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
public getRemoteColors(): RemoteEffectColorConfiguration[] {
|
|
76
|
+
return this.getColors().filter(
|
|
77
|
+
(colorConfiguration) => colorConfiguration.type === ClientColorType.Remote
|
|
78
|
+
) as RemoteEffectColorConfiguration[];
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ColorHSV,
|
|
3
|
+
colorToColorHSV,
|
|
4
|
+
ColorType as CoreColorType,
|
|
5
|
+
} from '@manganese/palette-kit-core';
|
|
6
|
+
import { ClientColorType } from '@manganese/palette-kit-client';
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
Context,
|
|
10
|
+
RandomEffectConfiguration,
|
|
11
|
+
EffectColorConfiguration,
|
|
12
|
+
ConstantEffectColorConfiguration,
|
|
13
|
+
DynamicEffectColorConfiguration,
|
|
14
|
+
RemoteEffectColorConfiguration,
|
|
15
|
+
NativeEffectType,
|
|
16
|
+
NativeEffectOption,
|
|
17
|
+
} from './types';
|
|
18
|
+
import { NATIVE_EFFECT_BASE } from './constants';
|
|
19
|
+
import {
|
|
20
|
+
colorToNanoleafColor,
|
|
21
|
+
nativeEffectTypeToPluginUuid,
|
|
22
|
+
} from './utilities';
|
|
23
|
+
import Effect from './Effect';
|
|
24
|
+
import Device from './Device';
|
|
25
|
+
|
|
26
|
+
export default class RandomEffect extends Effect<RandomEffectConfiguration> {
|
|
27
|
+
private colors = new Map<string /* color ID */, ColorHSV>();
|
|
28
|
+
|
|
29
|
+
constructor(configuration: RandomEffectConfiguration, context: Context) {
|
|
30
|
+
super(configuration, context);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public async initialize() {}
|
|
34
|
+
|
|
35
|
+
private getColor(colorConfiguration: EffectColorConfiguration) {
|
|
36
|
+
switch (colorConfiguration.type) {
|
|
37
|
+
case CoreColorType.Constant:
|
|
38
|
+
return (colorConfiguration as ConstantEffectColorConfiguration).color;
|
|
39
|
+
case CoreColorType.Dynamic:
|
|
40
|
+
case ClientColorType.Remote:
|
|
41
|
+
return this.colors.get(
|
|
42
|
+
(
|
|
43
|
+
colorConfiguration as
|
|
44
|
+
| DynamicEffectColorConfiguration
|
|
45
|
+
| RemoteEffectColorConfiguration
|
|
46
|
+
).id
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
public getNativeEffectForDevice(_device: Device) {
|
|
52
|
+
return {
|
|
53
|
+
...NATIVE_EFFECT_BASE,
|
|
54
|
+
...this.nativeEffectBase,
|
|
55
|
+
pluginUuid: nativeEffectTypeToPluginUuid(NativeEffectType.Random),
|
|
56
|
+
pluginOptions: [
|
|
57
|
+
{
|
|
58
|
+
name: 'delayTime',
|
|
59
|
+
value: this.configuration.delayTime,
|
|
60
|
+
} as NativeEffectOption,
|
|
61
|
+
{
|
|
62
|
+
name: 'transTime',
|
|
63
|
+
value: this.configuration.transitionTime,
|
|
64
|
+
} as NativeEffectOption,
|
|
65
|
+
],
|
|
66
|
+
palette: this.configuration.colors.map((colorConfiguration) => {
|
|
67
|
+
const color = this.getColor(colorConfiguration);
|
|
68
|
+
|
|
69
|
+
return colorToNanoleafColor(color, colorConfiguration.probability);
|
|
70
|
+
}),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
public getColors() {
|
|
75
|
+
return this.configuration.colors;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
public setColor(colorId: string, color: ColorHSV) {
|
|
79
|
+
this.colors.set(colorId, color);
|
|
80
|
+
this.handleChange();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ColorType, ColorHSV } from '@manganese/palette-kit-core';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
Context,
|
|
5
|
+
DynamicEffectColorConfiguration,
|
|
6
|
+
SolidEffectConfiguration,
|
|
7
|
+
} from './types';
|
|
8
|
+
import { NATIVE_EFFECT_BASE } from './constants';
|
|
9
|
+
import Effect from './Effect';
|
|
10
|
+
import Device from './Device';
|
|
11
|
+
|
|
12
|
+
const DEFAULT_COLOR_ID = 'default';
|
|
13
|
+
|
|
14
|
+
export default class SolidEffect extends Effect<SolidEffectConfiguration> {
|
|
15
|
+
private color: ColorHSV;
|
|
16
|
+
|
|
17
|
+
constructor(configuration: SolidEffectConfiguration, context: Context) {
|
|
18
|
+
super(configuration, context);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public async initialize() {}
|
|
22
|
+
|
|
23
|
+
public getNativeEffectForDevice(_device: Device) {
|
|
24
|
+
return {
|
|
25
|
+
...NATIVE_EFFECT_BASE,
|
|
26
|
+
...this.nativeEffectBase,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public getColors() {
|
|
31
|
+
return [this.configuration.color];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public setColor(_colorId: string, color: ColorHSV) {
|
|
35
|
+
this.color = color;
|
|
36
|
+
this.handleChange();
|
|
37
|
+
}
|
|
38
|
+
}
|