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.
Files changed (97) hide show
  1. package/.gitlab-ci.yml +24 -0
  2. package/README.md +9 -0
  3. package/dist/Device.d.ts +17 -0
  4. package/dist/Effect.d.ts +22 -0
  5. package/dist/RandomEffect.d.ts +23 -0
  6. package/dist/SolidEffect.d.ts +22 -0
  7. package/dist/WaveEffect.d.ts +23 -0
  8. package/dist/Zone.d.ts +26 -0
  9. package/dist/accessories/DynamicEffectColorAccessory.d.ts +5 -0
  10. package/dist/accessories/ZoneAccessory.d.ts +13 -0
  11. package/dist/accessories/index.d.ts +3 -0
  12. package/dist/constants.d.ts +9 -0
  13. package/dist/index.d.ts +2 -0
  14. package/dist/index.js +2 -0
  15. package/dist/index.js.LICENSE.txt +17 -0
  16. package/dist/platformFactory.d.ts +12 -0
  17. package/dist/types/Context.d.ts +9 -0
  18. package/dist/types/PlatformConfiguration.d.ts +6 -0
  19. package/dist/types/devices/DeviceConfiguration.d.ts +7 -0
  20. package/dist/types/devices/ZoneConfiguration.d.ts +8 -0
  21. package/dist/types/devices/index.d.ts +3 -0
  22. package/dist/types/effects/ConstantEffectColorConfiguration.d.ts +4 -0
  23. package/dist/types/effects/DynamicEffectColorConfiguration.d.ts +6 -0
  24. package/dist/types/effects/EffectColorConfiguration.d.ts +5 -0
  25. package/dist/types/effects/EffectColorConfigurationBase.d.ts +3 -0
  26. package/dist/types/effects/EffectColorType.d.ts +6 -0
  27. package/dist/types/effects/EffectConfiguration.d.ts +5 -0
  28. package/dist/types/effects/EffectConfigurationBase.d.ts +8 -0
  29. package/dist/types/effects/EffectType.d.ts +6 -0
  30. package/dist/types/effects/RemoteEffectColorConfiguration.d.ts +4 -0
  31. package/dist/types/effects/index.d.ts +14 -0
  32. package/dist/types/effects/native/NativeDirection.d.ts +7 -0
  33. package/dist/types/effects/native/NativeEffect.d.ts +13 -0
  34. package/dist/types/effects/native/NativeEffectColor.d.ts +6 -0
  35. package/dist/types/effects/native/NativeEffectOption.d.ts +18 -0
  36. package/dist/types/effects/native/NativeEffectType.d.ts +9 -0
  37. package/dist/types/effects/native/index.d.ts +6 -0
  38. package/dist/types/effects/random-effect/RandomEffectConfiguration.d.ts +9 -0
  39. package/dist/types/effects/random-effect/index.d.ts +2 -0
  40. package/dist/types/effects/solid-effect/SolidEffectColorConfiguration.d.ts +4 -0
  41. package/dist/types/effects/solid-effect/SolidEffectConfiguration.d.ts +7 -0
  42. package/dist/types/effects/solid-effect/index.d.ts +3 -0
  43. package/dist/types/effects/wave-effect/WaveEffectConfiguration.d.ts +11 -0
  44. package/dist/types/effects/wave-effect/index.d.ts +2 -0
  45. package/dist/types/index.d.ts +5 -0
  46. package/dist/utilities/HomebridgeLogAppender.d.ts +7 -0
  47. package/dist/utilities/colorToNanoleafColor.d.ts +4 -0
  48. package/dist/utilities/index.d.ts +4 -0
  49. package/dist/utilities/nativeEffectTypeToPluginUuid.d.ts +3 -0
  50. package/package.json +52 -0
  51. package/src/Device.ts +73 -0
  52. package/src/Effect.ts +80 -0
  53. package/src/RandomEffect.ts +82 -0
  54. package/src/SolidEffect.ts +38 -0
  55. package/src/WaveEffect.ts +95 -0
  56. package/src/Zone.ts +151 -0
  57. package/src/accessories/DynamicEffectColorAccessory.ts +19 -0
  58. package/src/accessories/ZoneAccessory.ts +46 -0
  59. package/src/accessories/index.ts +4 -0
  60. package/src/constants.ts +32 -0
  61. package/src/index.ts +11 -0
  62. package/src/platformFactory.ts +88 -0
  63. package/src/types/Context.ts +10 -0
  64. package/src/types/PlatformConfiguration.ts +7 -0
  65. package/src/types/devices/DeviceConfiguration.ts +7 -0
  66. package/src/types/devices/ZoneConfiguration.ts +9 -0
  67. package/src/types/devices/index.ts +4 -0
  68. package/src/types/effects/ConstantEffectColorConfiguration.ts +9 -0
  69. package/src/types/effects/DynamicEffectColorConfiguration.ts +12 -0
  70. package/src/types/effects/EffectColorConfiguration.ts +10 -0
  71. package/src/types/effects/EffectColorConfigurationBase.ts +3 -0
  72. package/src/types/effects/EffectColorType.ts +9 -0
  73. package/src/types/effects/EffectConfiguration.ts +10 -0
  74. package/src/types/effects/EffectConfigurationBase.ts +9 -0
  75. package/src/types/effects/EffectType.ts +7 -0
  76. package/src/types/effects/RemoteEffectColorConfiguration.ts +9 -0
  77. package/src/types/effects/index.ts +25 -0
  78. package/src/types/effects/native/NativeDirection.ts +8 -0
  79. package/src/types/effects/native/NativeEffect.ts +14 -0
  80. package/src/types/effects/native/NativeEffectColor.ts +6 -0
  81. package/src/types/effects/native/NativeEffectOption.ts +25 -0
  82. package/src/types/effects/native/NativeEffectType.ts +10 -0
  83. package/src/types/effects/native/index.ts +13 -0
  84. package/src/types/effects/random-effect/RandomEffectConfiguration.ts +11 -0
  85. package/src/types/effects/random-effect/index.ts +3 -0
  86. package/src/types/effects/solid-effect/SolidEffectColorConfiguration.ts +8 -0
  87. package/src/types/effects/solid-effect/SolidEffectConfiguration.ts +9 -0
  88. package/src/types/effects/solid-effect/index.ts +4 -0
  89. package/src/types/effects/wave-effect/WaveEffectConfiguration.ts +13 -0
  90. package/src/types/effects/wave-effect/index.ts +3 -0
  91. package/src/types/index.ts +6 -0
  92. package/src/utilities/HomebridgeLogAppender.ts +15 -0
  93. package/src/utilities/colorToNanoleafColor.ts +14 -0
  94. package/src/utilities/index.ts +9 -0
  95. package/src/utilities/nativeEffectTypeToPluginUuid.ts +4 -0
  96. package/tsconfig.json +21 -0
  97. 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,6 @@
1
+ import { ClientConfiguration } from '@manganese/palette-kit-client';
2
+ import { ZoneConfiguration } from './devices';
3
+ export default interface PlatformConfiguration {
4
+ paletteClient: ClientConfiguration;
5
+ zones: ZoneConfiguration[];
6
+ }
@@ -0,0 +1,7 @@
1
+ export default interface DeviceConfiguration {
2
+ id: string;
3
+ name: string;
4
+ ip: string;
5
+ token: string;
6
+ size?: number;
7
+ }
@@ -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,3 @@
1
+ import ZoneConfiguration from './ZoneConfiguration';
2
+ import DeviceConfiguration from './DeviceConfiguration';
3
+ export { ZoneConfiguration, DeviceConfiguration };
@@ -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,3 @@
1
+ export default interface EffectColorConfigurationBase {
2
+ probability?: number;
3
+ }
@@ -0,0 +1,6 @@
1
+ import { ClientColorType } from '@manganese/palette-kit-client';
2
+ declare enum NativeColorType {
3
+ Native = "native"
4
+ }
5
+ type EffectColorType = ClientColorType | NativeColorType;
6
+ export default EffectColorType;
@@ -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,8 @@
1
+ import EffectType from './EffectType';
2
+ export default interface EffectConfigurationBase {
3
+ type: EffectType;
4
+ name: string;
5
+ id: string;
6
+ nativeName?: string;
7
+ hapIdentifier: number;
8
+ }
@@ -0,0 +1,6 @@
1
+ declare enum EffectType {
2
+ Solid = "solid",
3
+ Wave = "wave",
4
+ Random = "random"
5
+ }
6
+ export default EffectType;
@@ -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,7 @@
1
+ declare enum NativeDirection {
2
+ Left = "left",
3
+ Right = "right",
4
+ Up = "up",
5
+ Down = "down"
6
+ }
7
+ export default NativeDirection;
@@ -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,6 @@
1
+ export default interface NativeEffectColor {
2
+ hue: number;
3
+ saturation: number;
4
+ brightness: number;
5
+ probability: number;
6
+ }
@@ -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,9 @@
1
+ declare enum NativeEffectType {
2
+ Wheel = "wheel",
3
+ Flow = "flow",
4
+ Explode = "explode",
5
+ Fade = "fade",
6
+ Random = "random",
7
+ Highlight = "highlight"
8
+ }
9
+ export default NativeEffectType;
@@ -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,2 @@
1
+ import RandomEffectConfiguration from './RandomEffectConfiguration';
2
+ export { RandomEffectConfiguration };
@@ -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,3 @@
1
+ import SolidEffectConfiguration from './SolidEffectConfiguration';
2
+ import SolidEffectColorConfiguration from './SolidEffectColorConfiguration';
3
+ export { SolidEffectConfiguration, SolidEffectColorConfiguration };
@@ -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,2 @@
1
+ import WaveEffectConfiguration from './WaveEffectConfiguration';
2
+ export { WaveEffectConfiguration };
@@ -0,0 +1,5 @@
1
+ import Context from './Context';
2
+ import PlatformConfiguration from './PlatformConfiguration';
3
+ export * from './devices';
4
+ export * from './effects';
5
+ export { Context, PlatformConfiguration };
@@ -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 { Color } from '@manganese/palette-kit-core';
2
+ import { NativeEffectColor } from '../types';
3
+ declare const _default: (color: Color, probability?: number) => NativeEffectColor;
4
+ export default _default;
@@ -0,0 +1,4 @@
1
+ import HomebridgeLogAppender from './HomebridgeLogAppender';
2
+ import colorToNanoleafColor from './colorToNanoleafColor';
3
+ import nativeEffectTypeToPluginUuid from './nativeEffectTypeToPluginUuid';
4
+ export { HomebridgeLogAppender, colorToNanoleafColor, nativeEffectTypeToPluginUuid, };
@@ -0,0 +1,3 @@
1
+ import { NativeEffectType } from '../types';
2
+ declare const _default: (type: NativeEffectType) => string;
3
+ export default _default;
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
+ }