@felixgeelhaar/govee-api-client 3.1.0 โ†’ 3.1.1

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 (2) hide show
  1. package/README.md +84 -550
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,661 +1,195 @@
1
- # Govee API TypeScript Client
1
+ # Govee API Client
2
2
 
3
- [![npm version](https://badge.fury.io/js/%40felixgeelhaar%2Fgovee-api-client.svg)](https://badge.fury.io/js/%40felixgeelhaar%2Fgovee-api-client)
4
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
3
+ [![npm version](https://img.shields.io/npm/v/@felixgeelhaar/govee-api-client)](https://www.npmjs.com/package/@felixgeelhaar/govee-api-client)
4
+ [![npm downloads](https://img.shields.io/npm/dm/@felixgeelhaar/govee-api-client)](https://www.npmjs.com/package/@felixgeelhaar/govee-api-client)
5
5
  [![CI](https://github.com/felixgeelhaar/govee-api-client/workflows/CI/badge.svg)](https://github.com/felixgeelhaar/govee-api-client/actions)
6
- [![codecov](https://codecov.io/gh/felixgeelhaar/govee-api-client/branch/main/graph/badge.svg)](https://codecov.io/gh/felixgeelhaar/govee-api-client)
7
-
8
- An enterprise-grade TypeScript client library for the Govee Developer REST API. Built with Domain-Driven Design (DDD) principles, comprehensive error handling, and production-ready rate limiting and retry capabilities.
9
-
10
- ## Features
6
+ [![Known Vulnerabilities](https://snyk.io/test/github/felixgeelhaar/govee-api-client/badge.svg)](https://snyk.io/test/github/felixgeelhaar/govee-api-client)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+ [![Node.js](https://img.shields.io/badge/node-%3E%3D20-brightgreen)](https://nodejs.org)
9
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.x-blue)](https://www.typescriptlang.org)
10
+ [![npm provenance](https://img.shields.io/badge/provenance-verified-brightgreen)](https://docs.npmjs.com/generating-provenance-statements)
11
11
 
12
- - ๐ŸŽฏ **Type-Safe**: Full TypeScript support with comprehensive type definitions
13
- - ๐Ÿ—๏ธ **Domain-Driven Design**: Clean architecture following DDD principles
14
- - โœ… **Runtime Validation**: Zod-based API response validation for production safety
15
- - โšก **Rate Limiting**: High-performance sliding window rate limiter with burst capability
16
- - ๐Ÿ”„ **Retry Logic**: Enterprise-grade retry with exponential backoff, jitter, and circuit breaker
17
- - ๐Ÿ›ก๏ธ **Error Handling**: Comprehensive error hierarchy with specific error types
18
- - ๐Ÿ“Š **Observability**: Built-in metrics and monitoring for rate limiting and retries
19
- - ๐Ÿ“ **Logging**: Configurable logging with Pino integration
20
- - ๐Ÿงช **Well Tested**: >95% test coverage with unit and integration tests
21
- - ๐Ÿš€ **Production Ready**: Enterprise-grade reliability and performance
12
+ A TypeScript client for the [Govee Developer API](https://developer.govee.com). Control your Govee lights, appliances, and other smart devices from code.
22
13
 
23
- ## Installation
14
+ ## Install
24
15
 
25
16
  ```bash
26
17
  npm install @felixgeelhaar/govee-api-client
27
18
  ```
28
19
 
29
- ## Quick Start
20
+ ## Getting Started
30
21
 
31
- ```typescript
32
- import {
33
- GoveeClient,
34
- Brightness,
35
- ColorRgb,
36
- ColorTemperature,
37
- } from '@felixgeelhaar/govee-api-client';
22
+ You'll need a Govee API key. Get one from the [Govee Developer Platform](https://developer.govee.com).
38
23
 
39
- // Initialize the client (uses GOVEE_API_KEY environment variable)
40
- const client = new GoveeClient();
24
+ ```typescript
25
+ import { GoveeClient, ColorRgb, Brightness } from '@felixgeelhaar/govee-api-client';
41
26
 
42
- // Or provide API key explicitly
43
- // const client = new GoveeClient({ apiKey: 'your-govee-api-key' });
27
+ const client = new GoveeClient({ apiKey: 'your-api-key' });
44
28
 
45
- // Get all devices
29
+ // List your devices
46
30
  const devices = await client.getDevices();
47
- console.log(`Found ${devices.length} devices`);
48
-
49
- // Find a specific device
50
- const livingRoomLight = await client.findDeviceByName('Living Room');
51
-
52
- if (livingRoomLight) {
53
- // Turn on the light with warm white and 75% brightness
54
- await client.turnOnWithColorTemperature(
55
- livingRoomLight.deviceId,
56
- livingRoomLight.model,
57
- ColorTemperature.warmWhite(),
58
- new Brightness(75)
59
- );
60
- }
61
- ```
62
-
63
- ## Configuration
64
31
 
65
- ### API Key
32
+ // Find and control a light
33
+ const light = await client.findDeviceByName('Living Room');
66
34
 
67
- The client reads the API key from the `GOVEE_API_KEY` environment variable by default:
68
-
69
- ```bash
70
- # Set environment variable
71
- export GOVEE_API_KEY=your-govee-api-key
72
-
73
- # Or use a .env file
74
- echo "GOVEE_API_KEY=your-govee-api-key" > .env
75
- ```
76
-
77
- ```typescript
78
- import { GoveeClient } from '@felixgeelhaar/govee-api-client';
79
-
80
- // Uses GOVEE_API_KEY environment variable automatically
81
- const client = new GoveeClient();
82
- ```
83
-
84
- You can also provide the API key explicitly (not recommended for production):
85
-
86
- ```typescript
87
- const client = new GoveeClient({
88
- apiKey: 'your-govee-api-key', // Explicit API key (overrides environment variable)
89
- });
35
+ if (light) {
36
+ await client.turnOn(light.deviceId, light.model);
37
+ await client.setBrightness(light.deviceId, light.model, new Brightness(75));
38
+ await client.setColor(light.deviceId, light.model, new ColorRgb(255, 120, 50));
39
+ }
90
40
  ```
91
41
 
92
- ### Full Configuration
42
+ You can also set the `GOVEE_API_KEY` environment variable and skip passing it to the constructor:
93
43
 
94
44
  ```typescript
95
- import pino from 'pino';
96
- import { GoveeClient, RetryPolicy } from '@felixgeelhaar/govee-api-client';
97
-
98
- const client = new GoveeClient({
99
- // apiKey is optional - uses GOVEE_API_KEY environment variable by default
100
- timeout: 30000, // Request timeout in milliseconds (default: 30000)
101
- rateLimit: 95, // Requests per minute (default: 95, with 5 buffer under Govee's limit)
102
- logger: pino({ level: 'info' }), // Optional logger (silent by default)
103
- enableRetries: true, // Enable retry functionality (default: false)
104
- retryPolicy: 'production', // Retry policy preset or custom RetryPolicy instance
105
- });
45
+ const client = new GoveeClient(); // reads from GOVEE_API_KEY
106
46
  ```
107
47
 
108
- ## API Reference
48
+ ## What You Can Do
109
49
 
110
- ### Device Management
50
+ ### Basic Controls
111
51
 
112
52
  ```typescript
113
- // Get all devices
114
- const devices = await client.getDevices();
115
-
116
- // Get only controllable devices
117
- const controllableDevices = await client.getControllableDevices();
118
-
119
- // Find device by name (case-insensitive)
120
- const device = await client.findDeviceByName('bedroom');
121
-
122
- // Find devices by model
123
- const devices = await client.findDevicesByModel('H6159');
124
-
125
- // Get device state
126
- const state = await client.getDeviceState(deviceId, model);
127
- console.log(`Power: ${state.getPowerState()}`);
128
- console.log(`Online: ${state.isOnline()}`);
53
+ await client.turnOn(deviceId, model);
54
+ await client.turnOff(deviceId, model);
55
+ await client.setBrightness(deviceId, model, new Brightness(75));
129
56
  ```
130
57
 
131
- ### Device Control
58
+ ### Colors
132
59
 
133
60
  ```typescript
134
- // Basic controls
135
- await client.turnOn(deviceId, model);
136
- await client.turnOff(deviceId, model);
137
- await client.setBrightness(deviceId, model, new Brightness(75));
61
+ import { ColorRgb, ColorTemperature } from '@felixgeelhaar/govee-api-client';
138
62
 
139
- // Color control
140
- const red = new ColorRgb(255, 0, 0);
141
- await client.setColor(deviceId, model, red);
63
+ // Set an RGB color
64
+ await client.setColor(deviceId, model, new ColorRgb(255, 0, 0));
142
65
 
143
- const coolWhite = new ColorTemperature(6500);
144
- await client.setColorTemperature(deviceId, model, coolWhite);
66
+ // Set a color temperature
67
+ await client.setColorTemperature(deviceId, model, ColorTemperature.warmWhite());
145
68
 
146
- // Convenience methods
147
- await client.turnOnWithBrightness(deviceId, model, new Brightness(50));
148
- await client.turnOnWithColor(deviceId, model, red, new Brightness(75));
149
- await client.turnOnWithColorTemperature(deviceId, model, coolWhite, new Brightness(100));
69
+ // Turn on with color and brightness in one call
70
+ await client.turnOnWithColor(deviceId, model, new ColorRgb(0, 255, 0), new Brightness(80));
150
71
  ```
151
72
 
152
- ### Advanced Light Control
153
-
154
- #### Dynamic Light Scenes
73
+ ### Scenes
155
74
 
156
75
  ```typescript
157
76
  import { LightScene } from '@felixgeelhaar/govee-api-client';
158
77
 
159
- // Get available dynamic scenes for a device
78
+ // Browse available scenes for a device
160
79
  const scenes = await client.getDynamicScenes(deviceId, model);
161
- console.log(`Available scenes: ${scenes.map(s => s.name).join(', ')}`);
162
80
 
163
- // Use built-in factory methods for common scenes
164
- await client.setLightScene(deviceId, model, LightScene.sunrise());
81
+ // Apply a built-in scene
165
82
  await client.setLightScene(deviceId, model, LightScene.sunset());
166
- await client.setLightScene(deviceId, model, LightScene.rainbow());
167
83
  await client.setLightScene(deviceId, model, LightScene.aurora());
168
-
169
- // Or set a custom scene
170
- const customScene = new LightScene(3853, 4280, 'My Scene');
171
- await client.setLightScene(deviceId, model, customScene);
172
84
  ```
173
85
 
174
- #### Segment Color Control (RGB IC Devices)
86
+ ### Segments (for LED strips and curtain lights)
175
87
 
176
88
  ```typescript
177
89
  import { SegmentColor, ColorRgb } from '@felixgeelhaar/govee-api-client';
178
90
 
179
- // Set color for individual segments
180
- const segment1 = new SegmentColor(0, new ColorRgb(255, 0, 0)); // Red
181
- const segment2 = new SegmentColor(1, new ColorRgb(0, 255, 0)); // Green
182
- const segment3 = new SegmentColor(2, new ColorRgb(0, 0, 255)); // Blue
183
-
184
- // Set multiple segments at once
185
- await client.setSegmentColors(deviceId, model, [segment1, segment2, segment3]);
186
-
187
- // Set brightness for individual segments
188
- await client.setSegmentBrightness(deviceId, model, [
189
- { index: 0, brightness: new Brightness(100) },
190
- { index: 1, brightness: new Brightness(75) },
191
- { index: 2, brightness: new Brightness(50) },
91
+ await client.setSegmentColors(deviceId, model, [
92
+ new SegmentColor(0, new ColorRgb(255, 0, 0)),
93
+ new SegmentColor(1, new ColorRgb(0, 255, 0)),
94
+ new SegmentColor(2, new ColorRgb(0, 0, 255)),
192
95
  ]);
193
96
  ```
194
97
 
195
- #### Music Mode
98
+ ### Music Mode
196
99
 
197
100
  ```typescript
198
101
  import { MusicMode } from '@felixgeelhaar/govee-api-client';
199
102
 
200
- // Set music mode with sensitivity
201
- const musicMode = new MusicMode(1, 75); // Mode 1, 75% sensitivity
202
- await client.setMusicMode(deviceId, model, musicMode);
203
-
204
- // Music mode without sensitivity (uses device default)
205
- const basicMode = new MusicMode(2);
206
- await client.setMusicMode(deviceId, model, basicMode);
103
+ await client.setMusicMode(deviceId, model, new MusicMode(1, 75));
207
104
  ```
208
105
 
209
- #### Toggle and Mode Controls
106
+ ### Toggles
210
107
 
211
108
  ```typescript
212
- // Nightlight toggle
213
- await client.setNightlightToggle(deviceId, model, true); // Enable
214
- await client.setNightlightToggle(deviceId, model, false); // Disable
215
-
216
- // Gradient toggle
109
+ await client.setNightlightToggle(deviceId, model, true);
217
110
  await client.setGradientToggle(deviceId, model, true);
218
-
219
- // Preset scenes
220
- await client.setNightlightScene(deviceId, model, 1); // Scene ID 1
221
- await client.setPresetScene(deviceId, model, 'cozy'); // Named scene
222
- ```
223
-
224
- ### Value Objects
225
-
226
- #### ColorRgb
227
-
228
- ```typescript
229
- // Create RGB colors
230
- const red = new ColorRgb(255, 0, 0);
231
- const blue = ColorRgb.fromHex('#0000FF');
232
- const green = ColorRgb.fromObject({ r: 0, g: 255, b: 0 });
233
-
234
- console.log(red.toHex()); // "#ff0000"
235
- console.log(blue.toString()); // "rgb(0, 0, 255)"
236
- ```
237
-
238
- #### ColorTemperature
239
-
240
- ```typescript
241
- // Create color temperatures
242
- const warm = ColorTemperature.warmWhite(); // 2700K
243
- const cool = ColorTemperature.coolWhite(); // 6500K
244
- const daylight = ColorTemperature.daylight(); // 5600K
245
- const custom = new ColorTemperature(4000);
246
-
247
- console.log(warm.isWarm()); // true
248
- console.log(cool.isCool()); // true
249
- ```
250
-
251
- #### Brightness
252
-
253
- ```typescript
254
- // Create brightness levels
255
- const dim = Brightness.dim(); // 25%
256
- const medium = Brightness.medium(); // 50%
257
- const bright = Brightness.bright(); // 75%
258
- const custom = new Brightness(85);
259
-
260
- console.log(bright.asPercent()); // 0.75
261
- console.log(custom.isDim()); // false
111
+ await client.setSceneStageToggle(deviceId, model, true);
262
112
  ```
263
113
 
264
- #### LightScene
114
+ ### Device State
265
115
 
266
116
  ```typescript
267
- import { LightScene } from '@felixgeelhaar/govee-api-client';
117
+ const state = await client.getDeviceState(deviceId, model);
268
118
 
269
- // Built-in factory methods for common dynamic scenes
270
- const sunrise = LightScene.sunrise();
271
- const sunset = LightScene.sunset();
272
- const rainbow = LightScene.rainbow();
273
- const aurora = LightScene.aurora();
274
- const candlelight = LightScene.candlelight();
275
- const nightlight = LightScene.nightlight();
276
- const romantic = LightScene.romantic();
277
- const blinking = LightScene.blinking();
278
-
279
- // Custom scene
280
- const custom = new LightScene(3853, 4280, 'My Custom Scene');
281
-
282
- // Scene properties
283
- console.log(sunrise.name); // "Sunrise"
284
- console.log(sunrise.id); // 3853
285
- console.log(sunrise.paramId); // 4280
119
+ console.log(state.getPowerState()); // true / false
120
+ console.log(state.isOnline()); // true / false
121
+ console.log(state.getBrightness()); // 0-100
286
122
  ```
287
123
 
288
- #### SegmentColor
124
+ ## Configuration
289
125
 
290
126
  ```typescript
291
- import { SegmentColor, ColorRgb, Brightness } from '@felixgeelhaar/govee-api-client';
292
-
293
- // Color only for a segment
294
- const segment1 = new SegmentColor(0, new ColorRgb(255, 0, 0));
295
-
296
- // Color with brightness for a segment
297
- const segment2 = new SegmentColor(1, new ColorRgb(0, 255, 0), new Brightness(75));
298
-
299
- // Check if segment has brightness
300
- console.log(segment1.hasBrightness()); // false
301
- console.log(segment2.hasBrightness()); // true
302
-
303
- // Access segment properties
304
- console.log(segment2.index); // 1
305
- console.log(segment2.color.toHex()); // "#00ff00"
306
- console.log(segment2.brightness?.level); // 75
127
+ const client = new GoveeClient({
128
+ apiKey: 'your-api-key',
129
+ timeout: 30000, // request timeout in ms (default: 30000)
130
+ rateLimit: 95, // requests per minute (default: 95)
131
+ enableRetries: true, // retry failed requests (default: false)
132
+ retryPolicy: 'production', // 'development', 'testing', or 'production'
133
+ });
307
134
  ```
308
135
 
309
- #### MusicMode
136
+ ### Rate Limiting
310
137
 
311
- ```typescript
312
- import { MusicMode } from '@felixgeelhaar/govee-api-client';
138
+ The client automatically stays within Govee's API rate limits (100 requests/min). By default it allows 95 requests/min, leaving a small buffer.
313
139
 
314
- // Music mode with sensitivity (0-100)
315
- const mode1 = new MusicMode(1, 75);
140
+ ### Retries
316
141
 
317
- // Music mode without sensitivity
318
- const mode2 = new MusicMode(2);
142
+ When enabled, failed requests are retried with exponential backoff. The built-in presets handle common scenarios:
319
143
 
320
- // Check if mode has sensitivity
321
- console.log(mode1.hasSensitivity()); // true
322
- console.log(mode2.hasSensitivity()); // false
144
+ - **production** โ€” 3 attempts, circuit breaker enabled
145
+ - **development** โ€” 5 attempts, circuit breaker disabled
146
+ - **testing** โ€” 2 attempts, conservative settings
323
147
 
324
- // Access properties
325
- console.log(mode1.modeId); // 1
326
- console.log(mode1.sensitivity); // 75
327
- ```
148
+ You can also pass a custom `RetryPolicy` instance for full control. See the [examples](docs/EXAMPLES.md) for details.
328
149
 
329
150
  ## Error Handling
330
151
 
331
- The library provides a comprehensive error hierarchy for different types of failures:
332
-
333
152
  ```typescript
334
153
  import {
335
154
  GoveeApiError,
336
155
  InvalidApiKeyError,
337
156
  RateLimitError,
338
157
  NetworkError,
339
- ValidationError,
340
158
  } from '@felixgeelhaar/govee-api-client';
341
159
 
342
160
  try {
343
- await client.getDevices();
161
+ await client.turnOn(deviceId, model);
344
162
  } catch (error) {
345
- if (error instanceof ValidationError) {
346
- // API returned malformed data that failed validation
347
- console.log('Validation error:', error.message);
348
-
349
- // Get detailed validation errors
350
- const details = error.getValidationDetails();
351
- details.forEach(detail => {
352
- console.log(` ${detail.path}: ${detail.message}`);
353
- console.log(` Received: ${JSON.stringify(detail.received)}`);
354
- });
355
-
356
- // Or get a summary string for logging
357
- console.log('Summary:', error.getValidationSummary());
358
- } else if (error instanceof InvalidApiKeyError) {
359
- console.log('API key is invalid or expired');
360
- console.log(error.getRecommendation());
163
+ if (error instanceof InvalidApiKeyError) {
164
+ console.log('Check your API key');
361
165
  } else if (error instanceof RateLimitError) {
362
- console.log(`Rate limited. Retry after: ${error.getRetryAfterMs()}ms`);
363
- } else if (error instanceof GoveeApiError) {
364
- console.log(`API Error: ${error.message}`);
365
- if (error.isDeviceOffline()) {
366
- console.log('Device is currently offline');
367
- }
166
+ console.log(`Too many requests. Retry in ${error.getRetryAfterMs()}ms`);
368
167
  } else if (error instanceof NetworkError) {
369
- console.log(`Network error: ${error.errorType}`);
370
- if (error.isRetryable()) {
371
- console.log('This error can be retried');
372
- }
168
+ console.log('Network issue โ€” retryable:', error.isRetryable());
169
+ } else if (error instanceof GoveeApiError) {
170
+ console.log('API error:', error.message);
373
171
  }
374
172
  }
375
173
  ```
376
174
 
377
- ### Runtime Validation
378
-
379
- All API responses are validated at runtime using Zod schemas to ensure data integrity:
380
-
381
- - **Automatic**: All API calls are validated transparently
382
- - **Type-safe**: Catches malformed responses before they reach your code
383
- - **Detailed errors**: `ValidationError` provides specific information about what failed
384
- - **Production-ready**: Protects against unexpected API changes
385
-
386
- If you need custom validation, the Zod schemas are exported:
387
-
388
- ```typescript
389
- import {
390
- GoveeDevicesResponseSchema,
391
- GoveeStateResponseSchema,
392
- GoveeCommandResponseSchema,
393
- } from '@felixgeelhaar/govee-api-client';
394
-
395
- // Use for custom validation scenarios
396
- const result = GoveeDevicesResponseSchema.safeParse(rawApiData);
397
- if (result.success) {
398
- console.log('Valid data:', result.data);
399
- } else {
400
- console.log('Validation errors:', result.error);
401
- }
402
- ```
403
-
404
- ## Rate Limiting & Retry Features
405
-
406
- The client includes enterprise-grade rate limiting and retry capabilities designed for production environments.
407
-
408
- ### Rate Limiting
409
-
410
- Uses a high-performance sliding window rate limiter that allows bursts up to the limit while maintaining the average rate over time:
411
-
412
- ```typescript
413
- const client = new GoveeClient({
414
- apiKey: 'your-api-key',
415
- rateLimit: 95, // Default: 95 req/min (5 request buffer under Govee's 100/min limit)
416
- });
417
-
418
- // Monitor rate limiter performance
419
- const stats = client.getRateLimiterStats();
420
- console.log(`Current utilization: ${stats.utilizationPercent}%`);
421
- console.log(`Queue size: ${stats.queueSize}`);
422
- console.log(`Can execute immediately: ${stats.canExecuteImmediately}`);
423
- ```
424
-
425
- ### Retry Logic
426
-
427
- Comprehensive retry functionality with exponential backoff, jitter, and circuit breaker:
428
-
429
- ```typescript
430
- const client = new GoveeClient({
431
- apiKey: 'your-api-key',
432
- enableRetries: true,
433
- retryPolicy: 'production', // 'development', 'testing', 'production'
434
- });
435
-
436
- // Monitor retry performance
437
- const retryMetrics = client.getRetryMetrics();
438
- if (retryMetrics) {
439
- console.log(`Total retry attempts: ${retryMetrics.totalAttempts}`);
440
- console.log(`Success rate: ${retryMetrics.successfulRetries}/${retryMetrics.totalAttempts}`);
441
- console.log(`Circuit breaker state: ${retryMetrics.circuitBreakerState}`);
442
- }
443
- ```
444
-
445
- ### Custom Retry Policies
446
-
447
- Create custom retry policies for specific requirements:
448
-
449
- ```typescript
450
- import {
451
- GoveeClient,
452
- RetryPolicy,
453
- RateLimitError,
454
- NetworkError,
455
- GoveeApiError,
456
- } from '@felixgeelhaar/govee-api-client';
457
-
458
- const customRetryPolicy = new RetryPolicy({
459
- backoff: {
460
- type: 'exponential',
461
- initialDelayMs: 1000,
462
- maxDelayMs: 30000,
463
- multiplier: 2.0,
464
- },
465
- jitter: {
466
- type: 'equal',
467
- factor: 0.1,
468
- },
469
- condition: {
470
- maxAttempts: 3,
471
- maxTotalTimeMs: 60000,
472
- retryableStatusCodes: [408, 429, 502, 503, 504],
473
- retryableErrorTypes: [RateLimitError, NetworkError, GoveeApiError],
474
- },
475
- circuitBreaker: {
476
- enabled: true,
477
- failureThreshold: 5,
478
- recoveryTimeoutMs: 30000,
479
- halfOpenSuccessThreshold: 2,
480
- },
481
- enableMetrics: true,
482
- });
483
-
484
- const client = new GoveeClient({
485
- apiKey: 'your-api-key',
486
- enableRetries: true,
487
- retryPolicy: customRetryPolicy,
488
- });
489
- ```
490
-
491
- ### Monitoring & Observability
492
-
493
- Get comprehensive metrics for monitoring and debugging:
494
-
495
- ```typescript
496
- // Get complete service statistics
497
- const serviceStats = client.getServiceStats();
498
- console.log('Rate Limiter:', serviceStats.rateLimiter);
499
- console.log('Retry Metrics:', serviceStats.retries);
500
- console.log('Configuration:', serviceStats.configuration);
501
-
502
- // Rate limiter specific stats
503
- const rateLimiterStats = client.getRateLimiterStats();
504
- console.log({
505
- currentRequests: rateLimiterStats.currentRequests,
506
- maxRequests: rateLimiterStats.maxRequests,
507
- utilizationPercent: rateLimiterStats.utilizationPercent,
508
- queueSize: rateLimiterStats.queueSize,
509
- canExecuteImmediately: rateLimiterStats.canExecuteImmediately,
510
- nextAvailableSlot: rateLimiterStats.nextAvailableSlot,
511
- });
512
-
513
- // Retry metrics (when retries are enabled)
514
- const retryMetrics = client.getRetryMetrics();
515
- if (retryMetrics) {
516
- console.log({
517
- totalAttempts: retryMetrics.totalAttempts,
518
- successfulRetries: retryMetrics.successfulRetries,
519
- failedRetries: retryMetrics.failedRetries,
520
- totalRetryTimeMs: retryMetrics.totalRetryTimeMs,
521
- averageRetryDelayMs: retryMetrics.averageRetryDelayMs,
522
- circuitBreakerState: retryMetrics.circuitBreakerState,
523
- lastError: retryMetrics.lastError?.message,
524
- lastRetryTimestamp: retryMetrics.lastRetryTimestamp,
525
- });
526
- }
527
-
528
- // Reset metrics for clean monitoring periods
529
- client.resetRetryMetrics();
530
- ```
531
-
532
- ### Retry Policy Presets
533
-
534
- The library includes three built-in retry policy presets optimized for different environments:
535
-
536
- #### Production (Default)
537
-
538
- - **Max attempts**: 3
539
- - **Backoff**: Exponential with 1s initial delay, 30s max
540
- - **Circuit breaker**: Enabled (5 failures to open, 30s recovery)
541
- - **Jitter**: Equal jitter to prevent thundering herd
542
-
543
- #### Development
544
-
545
- - **Max attempts**: 5
546
- - **Backoff**: Exponential with 500ms initial delay, 15s max
547
- - **Circuit breaker**: Disabled for easier debugging
548
- - **Jitter**: Full jitter for maximum randomization
549
-
550
- #### Testing
551
-
552
- - **Max attempts**: 2
553
- - **Backoff**: Exponential with 2s initial delay, 60s max
554
- - **Circuit breaker**: Enabled with conservative settings
555
- - **Jitter**: Decorrelated jitter for sophisticated patterns
556
-
557
- ### Performance Characteristics
558
-
559
- - **Rate Limiter**: High-performance sliding window allows concurrent execution within limits
560
- - **Memory Efficient**: Automatic cleanup of expired timestamps and bounded queue sizes
561
- - **Production Ready**: Circuit breaker prevents cascade failures
562
- - **Observable**: Comprehensive metrics for monitoring and alerting
563
-
564
- ## Domain-Driven Design
565
-
566
- The library follows DDD principles with clear separation of concerns:
567
-
568
- - **Entities**: `GoveeDevice`, `DeviceState`, `Command`
569
- - **Value Objects**: `ColorRgb`, `ColorTemperature`, `Brightness`
570
- - **Repositories**: `IGoveeDeviceRepository`, `GoveeDeviceRepository`
571
- - **Services**: `GoveeControlService`
572
- - **Errors**: Comprehensive error hierarchy
573
-
574
- ## Advanced Usage
575
-
576
- ### Custom Repository
577
-
578
- ```typescript
579
- import { GoveeControlService } from '@felixgeelhaar/govee-api-client';
580
-
581
- // Use your own repository implementation
582
- const service = new GoveeControlService({
583
- repository: new CustomGoveeRepository(),
584
- rateLimit: 120,
585
- });
586
- ```
587
-
588
- ### Command Pattern
589
-
590
- ```typescript
591
- import { CommandFactory } from '@felixgeelhaar/govee-api-client';
592
-
593
- // Create commands manually
594
- const powerOn = CommandFactory.powerOn();
595
- const setBrightness = CommandFactory.brightness(new Brightness(75));
596
-
597
- // Send custom commands
598
- await client.sendCommand(deviceId, model, powerOn);
599
- await client.sendCommand(deviceId, model, setBrightness);
600
- ```
601
-
602
175
  ## Requirements
603
176
 
604
- - Node.js 20.0.0 or higher
605
- - Valid Govee Developer API key
177
+ - Node.js 20 or higher
178
+ - A [Govee Developer API key](https://developer.govee.com)
606
179
 
607
180
  ## Development
608
181
 
609
182
  ```bash
610
- # Install dependencies
611
183
  npm install
612
-
613
- # Build the library
614
184
  npm run build
615
-
616
- # Run tests
617
185
  npm test
618
-
619
- # Run tests with coverage
620
186
  npm run test:coverage
621
-
622
- # Type checking
623
- npm run lint
624
187
  ```
625
188
 
626
- ## License
627
-
628
- MIT ยฉ [Felix Geelhaar]
629
-
630
189
  ## Contributing
631
190
 
632
- Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details on:
633
-
634
- - Code of conduct
635
- - Development workflow
636
- - Code standards and architecture
637
- - Testing requirements
638
- - Commit guidelines
639
- - Pull request process
640
-
641
- For feature requests and discussions, visit our [GitHub Discussions](https://github.com/felixgeelhaar/govee-api-client/discussions).
642
-
643
- ## Roadmap
191
+ Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
644
192
 
645
- See our [Product Roadmap](ROADMAP.md) for planned features and enhancements, including:
646
-
647
- - **Short-term (1-3 months):** Additional scene factory methods, animation utilities, performance optimizations
648
- - **Medium-term (3-6 months):** Device discovery, advanced scheduling, real-time monitoring
649
- - **Long-term (6-12 months):** Cloud integration, UI components, AI/ML features, ecosystem integrations
650
-
651
- We welcome feedback and contributions for any roadmap items!
652
-
653
- ## API Documentation
654
-
655
- For more information about the Govee Developer API, visit the official documentation:
193
+ ## License
656
194
 
657
- - **API Reference**: https://developer.govee.com/reference
658
- - **Getting Started**: https://developer.govee.com/docs
659
- - **Device Control**: https://developer.govee.com/reference/control-you-devices
660
- - **Device State**: https://developer.govee.com/reference/get-devices-status
661
- - **Get Devices**: https://developer.govee.com/reference/get-you-devices
195
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@felixgeelhaar/govee-api-client",
3
- "version": "3.1.0",
3
+ "version": "3.1.1",
4
4
  "description": "Enterprise-grade TypeScript client library for the Govee Developer REST API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",