@bobfrankston/lxlan 0.1.18 → 0.1.19
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/README.md +66 -38
- package/client.d.ts +5 -8
- package/client.js +7 -5
- package/device.d.ts +3 -26
- package/device.js +5 -39
- package/events.d.ts +4 -21
- package/events.js +3 -4
- package/index.d.ts +4 -6
- package/index.js +3 -5
- package/package.json +4 -2
- package/protocol.js +5 -5
- package/transport.d.ts +1 -1
- package/types.d.ts +0 -5
package/README.md
CHANGED
|
@@ -25,68 +25,87 @@ It does **NOT** know:
|
|
|
25
25
|
│ • LxClient - device discovery & management │
|
|
26
26
|
│ • LxDevice - individual device control │
|
|
27
27
|
│ • LxProtocol - message encode/decode │
|
|
28
|
-
│ • LxTransport -
|
|
28
|
+
│ • LxTransport - alias for UdpTransport │
|
|
29
29
|
├─────────────────────────────────────────────────┤
|
|
30
|
-
│ Transport
|
|
31
|
-
│ • @bobfrankston/
|
|
32
|
-
│ • @bobfrankston/
|
|
30
|
+
│ Shared Transport (pick one): │
|
|
31
|
+
│ • @bobfrankston/node-transport → Node dgram │
|
|
32
|
+
│ • @bobfrankston/browser-transport → httpudp WS │
|
|
33
|
+
├─────────────────────────────────────────────────┤
|
|
34
|
+
│ @bobfrankston/udp-transport (interface only) │
|
|
33
35
|
└─────────────────────────────────────────────────┘
|
|
34
36
|
```
|
|
35
37
|
|
|
38
|
+
**Legacy wrappers** (`lxlan-node`, `lxlan-browser`) pre-wire transport + event emitter and re-export everything. These are **deprecated** — use `@bobfrankston/lxlan` directly with a shared transport package instead (see Direct Usage below).
|
|
39
|
+
|
|
36
40
|
## Transport Abstraction
|
|
37
41
|
|
|
38
|
-
|
|
42
|
+
`LxTransport` is an alias for `UdpTransport` from `@bobfrankston/udp-transport`:
|
|
39
43
|
|
|
40
44
|
```typescript
|
|
41
|
-
export interface
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
export interface UdpTransport {
|
|
46
|
+
bind(): Promise<void>;
|
|
47
|
+
close(): void;
|
|
48
|
+
send(ip: string, port: number, data: Uint8Array): void;
|
|
49
|
+
broadcast(data: Uint8Array, port: number): void;
|
|
50
|
+
onMessage(handler: (data: Uint8Array, rinfo: RemoteInfo) => void): void;
|
|
51
|
+
onError(handler: (err: Error) => void): void;
|
|
52
|
+
onClose(handler: () => void): void;
|
|
48
53
|
}
|
|
49
54
|
```
|
|
50
55
|
|
|
51
|
-
**
|
|
52
|
-
- **Node.js**: `@bobfrankston/
|
|
53
|
-
- **Browser**: `@bobfrankston/
|
|
56
|
+
**Shared transport implementations:**
|
|
57
|
+
- **Node.js**: `NodeUdpTransport` from `@bobfrankston/node-transport` (dgram)
|
|
58
|
+
- **Browser**: `BrowserUdpTransport` from `@bobfrankston/browser-transport` (httpudp WebSocket)
|
|
54
59
|
|
|
55
|
-
|
|
60
|
+
See [transport-architecture.md](../../../../doc/transport-architecture.md) for the full transport stack reference.
|
|
56
61
|
|
|
57
|
-
|
|
62
|
+
## Installation
|
|
58
63
|
|
|
59
64
|
```bash
|
|
60
|
-
|
|
61
|
-
npm install @bobfrankston/lxlan-node
|
|
62
|
-
|
|
63
|
-
# For browser projects
|
|
64
|
-
npm install @bobfrankston/lxlan-browser
|
|
65
|
+
npm install @bobfrankston/lxlan
|
|
65
66
|
```
|
|
66
67
|
|
|
67
|
-
|
|
68
|
+
Then pick a transport for your platform:
|
|
68
69
|
|
|
69
70
|
```bash
|
|
70
|
-
|
|
71
|
+
# Node.js
|
|
72
|
+
npm install @bobfrankston/node-transport
|
|
73
|
+
|
|
74
|
+
# Browser
|
|
75
|
+
npm install @bobfrankston/browser-transport
|
|
71
76
|
```
|
|
72
77
|
|
|
73
|
-
|
|
78
|
+
> **Note:** The legacy convenience wrappers `@bobfrankston/lxlan-node` and `@bobfrankston/lxlan-browser` are **deprecated**. Use `@bobfrankston/lxlan` directly with a shared transport package instead.
|
|
74
79
|
|
|
75
|
-
|
|
80
|
+
## Direct Usage (No Wrapper)
|
|
81
|
+
|
|
82
|
+
Pass a transport factory — LxClient creates the transport and emitter internally:
|
|
76
83
|
|
|
77
84
|
```typescript
|
|
78
85
|
import { LxClient } from '@bobfrankston/lxlan';
|
|
79
|
-
import {
|
|
86
|
+
import { NodeUdpTransport } from '@bobfrankston/node-transport';
|
|
80
87
|
|
|
81
|
-
const
|
|
82
|
-
|
|
88
|
+
const client = new LxClient({
|
|
89
|
+
Transport: NodeUdpTransport, // has static .create(port)
|
|
90
|
+
});
|
|
83
91
|
|
|
84
92
|
await client.start();
|
|
85
93
|
|
|
86
94
|
client.on('device', (device) => {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
95
|
+
console.log('Found:', device.label);
|
|
96
|
+
device.setPower(true);
|
|
97
|
+
device.setColor({ h: 120, s: 100, b: 50 });
|
|
98
|
+
});
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
For custom transport config (e.g., browser with specific httpudp URL):
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
import { LxClient } from '@bobfrankston/lxlan';
|
|
105
|
+
import { BrowserUdpTransport } from '@bobfrankston/browser-transport';
|
|
106
|
+
|
|
107
|
+
const client = new LxClient({
|
|
108
|
+
Transport: { create: (port) => new BrowserUdpTransport({ httpudpUrl: 'ws://myserver:8080' }) },
|
|
90
109
|
});
|
|
91
110
|
```
|
|
92
111
|
|
|
@@ -101,6 +120,10 @@ client.on('device', (device) => {
|
|
|
101
120
|
- 🔄 Automatic retry with configurable timeouts
|
|
102
121
|
- 📝 Comprehensive device info (firmware, WiFi, uptime)
|
|
103
122
|
|
|
123
|
+
## LxDevice
|
|
124
|
+
|
|
125
|
+
Extends [`DeviceBase`](../../../../Others/deviceapi/devdefs) from `@bobfrankston/devdefs` — shared state (`mac`, `ip`, `port`, `power`, `label`, `online`, `lastSeen`, `markSeen()`) and transport plumbing. See [devdefs README](../../../../Others/deviceapi/devdefs/README.md) for base class details and MAC utilities (`mac12`, `macmac`).
|
|
126
|
+
|
|
104
127
|
## Device Control
|
|
105
128
|
|
|
106
129
|
```typescript
|
|
@@ -144,11 +167,12 @@ client.on('deviceInfo', (device) => {
|
|
|
144
167
|
|
|
145
168
|
## Dependencies
|
|
146
169
|
|
|
170
|
+
- `@bobfrankston/devdefs` - Shared device base class (`DeviceBase`, `mac12`, `macmac`)
|
|
147
171
|
- `@bobfrankston/colorlib` - Color space conversions (HSB ↔ RGB ↔ Kelvin)
|
|
148
172
|
|
|
149
|
-
##
|
|
173
|
+
## Legacy Wrappers (Deprecated)
|
|
150
174
|
|
|
151
|
-
|
|
175
|
+
`lxlan-node` and `lxlan-browser` are legacy convenience wrappers that pre-wire transport + event emitter. They still work but are **deprecated** — prefer direct usage with shared transport packages. No new features will be added to the wrappers.
|
|
152
176
|
|
|
153
177
|
## Importing Types
|
|
154
178
|
|
|
@@ -160,12 +184,16 @@ import type { StateEventInfo, DeviceState } from '@bobfrankston/lxlan';
|
|
|
160
184
|
|
|
161
185
|
## Related Packages
|
|
162
186
|
|
|
163
|
-
- **[@bobfrankston/
|
|
164
|
-
- **[@bobfrankston/lxlan-
|
|
165
|
-
- **[@bobfrankston/
|
|
166
|
-
- **[@bobfrankston/
|
|
187
|
+
- **[@bobfrankston/devdefs](../../../../Others/deviceapi/devdefs)** - Shared device base class and MAC utilities
|
|
188
|
+
- **[@bobfrankston/lxlan-node](../lxlan-node)** - Node.js convenience wrapper (deprecated)
|
|
189
|
+
- **[@bobfrankston/lxlan-browser](../lxlan-browser)** - Browser convenience wrapper (deprecated)
|
|
190
|
+
- **[@bobfrankston/udp-transport](../../../../utils/udp/udp-transport)** - UdpTransport interface definition
|
|
191
|
+
- **[@bobfrankston/node-transport](../../../../utils/udp/node-transport)** - Shared Node.js UDP transport (NodeUdpTransport, NodeEventEmitter)
|
|
192
|
+
- **[@bobfrankston/browser-transport](../../../../utils/udp/browser-transport)** - Shared browser UDP transport (BrowserUdpTransport, BrowserEventEmitter)
|
|
167
193
|
- **[@bobfrankston/httpudp](../../../../utils/udp/httpudp)** - WebSocket-to-UDP proxy server
|
|
194
|
+
- **[@bobfrankston/httpudp-client](../../../../utils/udp/httpudp-client)** - Browser WebSocket UDP client (used by browser-transport)
|
|
168
195
|
- **[@bobfrankston/colorlib](../../../../utils/colorlib)** - Color utilities
|
|
196
|
+
- **[Transport Architecture](../../../../doc/transport-architecture.md)** - Full transport stack reference
|
|
169
197
|
|
|
170
198
|
## TypeScript Configuration
|
|
171
199
|
|
package/client.d.ts
CHANGED
|
@@ -1,21 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { LxEventEmitter } from './events.js';
|
|
1
|
+
import type { UdpTransportFactory } from '@bobfrankston/udp-transport';
|
|
3
2
|
import { LxDevice } from './device.js';
|
|
4
3
|
/**
|
|
5
4
|
* Options for LxClient constructor
|
|
6
5
|
*/
|
|
7
6
|
export interface LxClientOptions {
|
|
8
|
-
/** Transport
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
eventEmitter: LxEventEmitter;
|
|
12
|
-
/** LIFX port (default 56700) */
|
|
7
|
+
/** Transport factory — must have .create(port) (e.g. NodeUdpTransport, BrowserUdpTransport) */
|
|
8
|
+
Transport: UdpTransportFactory;
|
|
9
|
+
/** LIFX port override (default 56700) */
|
|
13
10
|
port?: number;
|
|
14
11
|
/** Auto-discovery interval in ms (0 = manual only, default 0) */
|
|
15
12
|
discoveryInterval?: number;
|
|
16
13
|
/** Enable client-to-client state broadcast for multi-client sync (default false) */
|
|
17
14
|
clientBroadcastEnabled?: boolean;
|
|
18
|
-
/** Custom logger function (default:
|
|
15
|
+
/** Custom logger function (default: no-op) */
|
|
19
16
|
logger?: (msg: string, colors?: string) => void;
|
|
20
17
|
}
|
|
21
18
|
/**
|
package/client.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { hsbk16ToHsbk } from '@bobfrankston/colorlib';
|
|
2
|
+
import { SimpleEventEmitter } from '@bobfrankston/udp-transport';
|
|
3
|
+
import { mac12 } from '@bobfrankston/devdefs';
|
|
2
4
|
import { LxDevice } from './device.js';
|
|
3
5
|
import { MessageType, LIFX_PORT, MessageTypeName } from './types.js';
|
|
4
6
|
import { encodeMessage, decodeMessage, decodeState, decodeStatePower, decodeStateLabel, decodeStateVersion, decodeStateGroup, decodeStateService, decodeStateHostInfo, decodeStateHostFirmware, decodeStateWifiInfo, decodeStateInfo } from './protocol.js';
|
|
@@ -33,11 +35,11 @@ export class LxClient {
|
|
|
33
35
|
/** Cached devices by MAC address (lowercase) */
|
|
34
36
|
devices = new Map();
|
|
35
37
|
constructor(options) {
|
|
36
|
-
this.emitter =
|
|
37
|
-
this.transport = options.transport;
|
|
38
|
+
this.emitter = new SimpleEventEmitter();
|
|
38
39
|
this.port = options.port ?? LIFX_PORT;
|
|
40
|
+
this.transport = options.Transport.create(this.port);
|
|
39
41
|
this.clientBroadcastEnabled = options.clientBroadcastEnabled ?? false;
|
|
40
|
-
this.log = options.logger ?? ((
|
|
42
|
+
this.log = options.logger ?? (() => { });
|
|
41
43
|
this.transport.onMessage((data, rinfo) => {
|
|
42
44
|
// Ensure data is Uint8Array for protocol decoder
|
|
43
45
|
const buf = data instanceof Uint8Array ? data : new Uint8Array(data);
|
|
@@ -109,7 +111,7 @@ export class LxClient {
|
|
|
109
111
|
* @returns LxDevice or undefined if not found
|
|
110
112
|
*/
|
|
111
113
|
getDevice(mac) {
|
|
112
|
-
return this.devices.get(mac
|
|
114
|
+
return this.devices.get(mac12(mac));
|
|
113
115
|
}
|
|
114
116
|
/**
|
|
115
117
|
* Add device manually (bypassing discovery).
|
|
@@ -121,7 +123,7 @@ export class LxClient {
|
|
|
121
123
|
* @returns LxDevice instance (new or existing)
|
|
122
124
|
*/
|
|
123
125
|
addDevice(mac, ip, port = LIFX_PORT) {
|
|
124
|
-
const normalizedMac = mac
|
|
126
|
+
const normalizedMac = mac12(mac);
|
|
125
127
|
let device = this.devices.get(normalizedMac);
|
|
126
128
|
if (!device) {
|
|
127
129
|
device = new LxDevice(normalizedMac, ip);
|
package/device.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { DeviceBase } from '@bobfrankston/devdefs';
|
|
1
2
|
import { HSBK, ColorInput } from '@bobfrankston/colorlib';
|
|
2
|
-
import { LxTransport } from './transport.js';
|
|
3
3
|
import { GroupInfo } from './types.js';
|
|
4
4
|
/**
|
|
5
5
|
* Represents a LIFX device on the LAN.
|
|
@@ -9,23 +9,9 @@ import { GroupInfo } from './types.js';
|
|
|
9
9
|
* Always use `client.addDevice(mac, ip)` or obtain devices from `client.devices`.
|
|
10
10
|
* Directly instantiated devices will not have a transport and will fail at runtime.
|
|
11
11
|
*/
|
|
12
|
-
export declare class LxDevice {
|
|
13
|
-
/** MAC address (lowercase, colon-separated) */
|
|
14
|
-
readonly mac: string;
|
|
15
|
-
/** Current IP address */
|
|
16
|
-
ip: string;
|
|
17
|
-
/** UDP port (default LIFX_PORT = 56700) */
|
|
18
|
-
port: number;
|
|
19
|
-
/** Power state (true = on) */
|
|
20
|
-
power: boolean;
|
|
12
|
+
export declare class LxDevice extends DeviceBase {
|
|
21
13
|
/** Current color in HSBK format */
|
|
22
14
|
color: HSBK;
|
|
23
|
-
/** Device label (user-assigned name) */
|
|
24
|
-
label: string;
|
|
25
|
-
/** Whether device is responding */
|
|
26
|
-
online: boolean;
|
|
27
|
-
/** Last message timestamp (Date.now()) */
|
|
28
|
-
lastSeen: number;
|
|
29
15
|
/** Vendor ID (1 = LIFX) */
|
|
30
16
|
vendor: number;
|
|
31
17
|
/** Product ID (see Products table) */
|
|
@@ -46,7 +32,6 @@ export declare class LxDevice {
|
|
|
46
32
|
location: GroupInfo;
|
|
47
33
|
/** Recent messages for deduplication (sequence:type -> timestamp) */
|
|
48
34
|
private recentMessages;
|
|
49
|
-
private transport?;
|
|
50
35
|
/** Pending requests awaiting responses (message type -> timeout) */
|
|
51
36
|
private pendingRequests;
|
|
52
37
|
/** Default timeout for requests in milliseconds */
|
|
@@ -58,19 +43,13 @@ export declare class LxDevice {
|
|
|
58
43
|
* Do not call directly - use `client.addDevice(mac, ip)` instead.
|
|
59
44
|
* Devices created directly will not have a transport and will throw errors when used.
|
|
60
45
|
*
|
|
61
|
-
* @param mac - MAC address (will be normalized to lowercase)
|
|
46
|
+
* @param mac - MAC address (will be normalized to lowercase, no separators)
|
|
62
47
|
* @param ip - IP address (optional, can be discovered)
|
|
63
48
|
* @internal
|
|
64
49
|
*/
|
|
65
50
|
constructor(mac: string, ip?: string);
|
|
66
|
-
/** Throw error if transport is not set */
|
|
67
|
-
private requireTransport;
|
|
68
|
-
/** Throw error if IP address is not set */
|
|
69
|
-
private requireIP;
|
|
70
51
|
/** Get product name from product ID */
|
|
71
52
|
get productName(): string;
|
|
72
|
-
/** Set the transport (used by LxClient when managing devices) */
|
|
73
|
-
setTransport(transport: LxTransport): void;
|
|
74
53
|
/** Send raw message to device */
|
|
75
54
|
send(type: number, payload?: Buffer): void;
|
|
76
55
|
/** Start tracking a request with timeout */
|
|
@@ -143,8 +122,6 @@ export declare class LxDevice {
|
|
|
143
122
|
* Listen for 'deviceInfo' event on client to get results.
|
|
144
123
|
*/
|
|
145
124
|
getDeviceInfo(): void;
|
|
146
|
-
/** Update last seen timestamp and online status */
|
|
147
|
-
markSeen(): void;
|
|
148
125
|
/** Notify that a response was received for a message type */
|
|
149
126
|
markResponseReceived(messageType: number): void;
|
|
150
127
|
/**
|
package/device.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DeviceBase } from '@bobfrankston/devdefs';
|
|
1
2
|
import { parseColor, hsbkTo16 } from '@bobfrankston/colorlib';
|
|
2
3
|
import { MessageType, Products, LIFX_PORT } from './types.js';
|
|
3
4
|
import { encodeMessage, encodeSetPower, encodeSetColor, encodeSetWaveformOptional, encodeSetLabel, encodeSetGroup, encodeSetLocation } from './protocol.js';
|
|
@@ -9,23 +10,9 @@ import { encodeMessage, encodeSetPower, encodeSetColor, encodeSetWaveformOptiona
|
|
|
9
10
|
* Always use `client.addDevice(mac, ip)` or obtain devices from `client.devices`.
|
|
10
11
|
* Directly instantiated devices will not have a transport and will fail at runtime.
|
|
11
12
|
*/
|
|
12
|
-
export class LxDevice {
|
|
13
|
-
/** MAC address (lowercase, colon-separated) */
|
|
14
|
-
mac;
|
|
15
|
-
/** Current IP address */
|
|
16
|
-
ip;
|
|
17
|
-
/** UDP port (default LIFX_PORT = 56700) */
|
|
18
|
-
port = LIFX_PORT;
|
|
19
|
-
/** Power state (true = on) */
|
|
20
|
-
power = false;
|
|
13
|
+
export class LxDevice extends DeviceBase {
|
|
21
14
|
/** Current color in HSBK format */
|
|
22
15
|
color = { h: 0, s: 0, b: 0, k: 3500 };
|
|
23
|
-
/** Device label (user-assigned name) */
|
|
24
|
-
label = '';
|
|
25
|
-
/** Whether device is responding */
|
|
26
|
-
online = false;
|
|
27
|
-
/** Last message timestamp (Date.now()) */
|
|
28
|
-
lastSeen = 0;
|
|
29
16
|
/** Vendor ID (1 = LIFX) */
|
|
30
17
|
vendor = 0;
|
|
31
18
|
/** Product ID (see Products table) */
|
|
@@ -46,7 +33,6 @@ export class LxDevice {
|
|
|
46
33
|
location = { id: '', label: '', updatedAt: 0 };
|
|
47
34
|
/** Recent messages for deduplication (sequence:type -> timestamp) */
|
|
48
35
|
recentMessages = new Map();
|
|
49
|
-
transport;
|
|
50
36
|
/** Pending requests awaiting responses (message type -> timeout) */
|
|
51
37
|
pendingRequests = new Map();
|
|
52
38
|
/** Default timeout for requests in milliseconds */
|
|
@@ -58,32 +44,17 @@ export class LxDevice {
|
|
|
58
44
|
* Do not call directly - use `client.addDevice(mac, ip)` instead.
|
|
59
45
|
* Devices created directly will not have a transport and will throw errors when used.
|
|
60
46
|
*
|
|
61
|
-
* @param mac - MAC address (will be normalized to lowercase)
|
|
47
|
+
* @param mac - MAC address (will be normalized to lowercase, no separators)
|
|
62
48
|
* @param ip - IP address (optional, can be discovered)
|
|
63
49
|
* @internal
|
|
64
50
|
*/
|
|
65
51
|
constructor(mac, ip) {
|
|
66
|
-
|
|
67
|
-
this.ip = ip || '';
|
|
68
|
-
}
|
|
69
|
-
/** Throw error if transport is not set */
|
|
70
|
-
requireTransport() {
|
|
71
|
-
if (!this.transport)
|
|
72
|
-
throw new Error(`Device ${this.mac} has no UDP transport - cannot send. Use lxlan-node or lxlan-http.`);
|
|
73
|
-
}
|
|
74
|
-
/** Throw error if IP address is not set */
|
|
75
|
-
requireIP() {
|
|
76
|
-
if (!this.ip)
|
|
77
|
-
throw new Error(`Device ${this.mac} has no IP address - cannot send. Perform discovery or add device with IP using client.addDevice(mac, ip).`);
|
|
52
|
+
super(mac, ip, LIFX_PORT);
|
|
78
53
|
}
|
|
79
54
|
/** Get product name from product ID */
|
|
80
55
|
get productName() {
|
|
81
56
|
return Products[this.product] ?? `Unknown (${this.product})`;
|
|
82
57
|
}
|
|
83
|
-
/** Set the transport (used by LxClient when managing devices) */
|
|
84
|
-
setTransport(transport) {
|
|
85
|
-
this.transport = transport;
|
|
86
|
-
}
|
|
87
58
|
/** Send raw message to device */
|
|
88
59
|
send(type, payload) {
|
|
89
60
|
this.requireTransport();
|
|
@@ -197,7 +168,7 @@ export class LxDevice {
|
|
|
197
168
|
* @param brightness - Brightness 0-100 (default 100)
|
|
198
169
|
* @param duration - Transition time in milliseconds (default 0)
|
|
199
170
|
*/
|
|
200
|
-
setWhite(kelvin, brightness =
|
|
171
|
+
setWhite(kelvin, brightness = LxDevice.MaxBrightness, duration = 0) {
|
|
201
172
|
this.setColor({ h: 0, s: 0, b: brightness, k: kelvin }, duration);
|
|
202
173
|
}
|
|
203
174
|
/** Query full state */
|
|
@@ -285,11 +256,6 @@ export class LxDevice {
|
|
|
285
256
|
this.getInfo();
|
|
286
257
|
this.getState();
|
|
287
258
|
}
|
|
288
|
-
/** Update last seen timestamp and online status */
|
|
289
|
-
markSeen() {
|
|
290
|
-
this.lastSeen = Date.now();
|
|
291
|
-
this.online = true;
|
|
292
|
-
}
|
|
293
259
|
/** Notify that a response was received for a message type */
|
|
294
260
|
markResponseReceived(messageType) {
|
|
295
261
|
this.clearRequestTimeout(messageType);
|
package/events.d.ts
CHANGED
|
@@ -1,24 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Browser implementations can provide their own or use a library
|
|
2
|
+
* Re-export shared event emitter types from @bobfrankston/udp-transport.
|
|
3
|
+
* LxEventEmitter is kept as an alias for backwards compatibility.
|
|
5
4
|
*/
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
once(event: string, listener: (...args: any[]) => void): this;
|
|
9
|
-
off(event: string, listener: (...args: any[]) => void): this;
|
|
10
|
-
emit(event: string, ...args: any[]): boolean;
|
|
11
|
-
removeAllListeners(event?: string): this;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Base class for objects that emit events
|
|
15
|
-
* This is platform-agnostic and can be implemented for Node.js or browser
|
|
16
|
-
*/
|
|
17
|
-
export declare abstract class LxEventEmitterBase implements LxEventEmitter {
|
|
18
|
-
abstract on(event: string, listener: (...args: any[]) => void): this;
|
|
19
|
-
abstract once(event: string, listener: (...args: any[]) => void): this;
|
|
20
|
-
abstract off(event: string, listener: (...args: any[]) => void): this;
|
|
21
|
-
abstract emit(event: string, ...args: any[]): boolean;
|
|
22
|
-
abstract removeAllListeners(event?: string): this;
|
|
23
|
-
}
|
|
5
|
+
export { LanEventEmitter, SimpleEventEmitter } from '@bobfrankston/udp-transport';
|
|
6
|
+
export { LanEventEmitter as LxEventEmitter } from '@bobfrankston/udp-transport';
|
|
24
7
|
//# sourceMappingURL=events.d.ts.map
|
package/events.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* Re-export shared event emitter types from @bobfrankston/udp-transport.
|
|
3
|
+
* LxEventEmitter is kept as an alias for backwards compatibility.
|
|
4
4
|
*/
|
|
5
|
-
export
|
|
6
|
-
}
|
|
5
|
+
export { SimpleEventEmitter } from '@bobfrankston/udp-transport';
|
|
7
6
|
//# sourceMappingURL=events.js.map
|
package/index.d.ts
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @bobfrankston/lxlan — Platform-agnostic LIFX LAN protocol core.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* - Node.js: @bobfrankston/lxlan-node
|
|
7
|
-
* - Browser: @bobfrankston/lxlan-browser
|
|
4
|
+
* Usage: pass a UdpTransportFactory (e.g. NodeUdpTransport, BrowserUdpTransport).
|
|
5
|
+
* The client creates transport and event emitter internally.
|
|
8
6
|
*/
|
|
9
7
|
export * from './types.js';
|
|
10
8
|
export { LxDevice } from './device.js';
|
|
11
9
|
export { LxClient, LxClientOptions } from './client.js';
|
|
12
|
-
export { UdpTransport, LxTransport, RemoteInfo } from './transport.js';
|
|
13
|
-
export { LxEventEmitter,
|
|
10
|
+
export { UdpTransport, UdpTransportFactory, LxTransport, RemoteInfo, StateEventInfo } from './transport.js';
|
|
11
|
+
export { LxEventEmitter, LanEventEmitter, SimpleEventEmitter } from './events.js';
|
|
14
12
|
export { encodeMessage, decodeMessage, encodeSetWifiConfiguration, encodeGetWifiConfiguration, decodeStateWifiConfiguration, encodeSetLabel, encodeSetColor, encodeSetPower, encodeSetGroup, encodeSetLocation, encodeSetWaveformOptional, encodeGetService, decodeState, decodeStatePower, decodeStateLabel, decodeStateVersion, decodeStateGroup, decodeStateService, decodeStateHostInfo, decodeStateHostFirmware, decodeStateWifiInfo, decodeStateInfo, FrameFlags, ProtocolBits, nextSequence, getSource, } from './protocol.js';
|
|
15
13
|
//# sourceMappingURL=index.d.ts.map
|
package/index.js
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @bobfrankston/lxlan — Platform-agnostic LIFX LAN protocol core.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* - Node.js: @bobfrankston/lxlan-node
|
|
7
|
-
* - Browser: @bobfrankston/lxlan-browser
|
|
4
|
+
* Usage: pass a UdpTransportFactory (e.g. NodeUdpTransport, BrowserUdpTransport).
|
|
5
|
+
* The client creates transport and event emitter internally.
|
|
8
6
|
*/
|
|
9
7
|
export * from './types.js';
|
|
10
8
|
export { LxDevice } from './device.js';
|
|
11
9
|
export { LxClient } from './client.js';
|
|
12
|
-
export {
|
|
10
|
+
export { SimpleEventEmitter } from './events.js';
|
|
13
11
|
export { encodeMessage, decodeMessage, encodeSetWifiConfiguration, encodeGetWifiConfiguration, decodeStateWifiConfiguration, encodeSetLabel, encodeSetColor, encodeSetPower, encodeSetGroup, encodeSetLocation, encodeSetWaveformOptional, encodeGetService, decodeState, decodeStatePower, decodeStateLabel, decodeStateVersion, decodeStateGroup, decodeStateService, decodeStateHostInfo, decodeStateHostFirmware, decodeStateWifiInfo, decodeStateInfo, FrameFlags, ProtocolBits, nextSequence, getSource, } from './protocol.js';
|
|
14
12
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bobfrankston/lxlan",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.19",
|
|
4
4
|
"description": "LIFX LAN protocol library for device control via UDP",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -32,16 +32,18 @@
|
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@bobfrankston/colorlib": "^0.1.8",
|
|
35
|
+
"@bobfrankston/devdefs": "^0.1.0",
|
|
35
36
|
"@bobfrankston/udp-transport": "^1.0.2"
|
|
36
37
|
},
|
|
37
38
|
"devDependencies": {
|
|
38
|
-
"@types/node": "^25.
|
|
39
|
+
"@types/node": "^25.3.0"
|
|
39
40
|
},
|
|
40
41
|
"publishConfig": {
|
|
41
42
|
"access": "public"
|
|
42
43
|
},
|
|
43
44
|
".dependencies": {
|
|
44
45
|
"@bobfrankston/colorlib": "file:../../../../utils/colorlib",
|
|
46
|
+
"@bobfrankston/devdefs": "file:../../../../Others/deviceapi/devdefs",
|
|
45
47
|
"@bobfrankston/udp-transport": "file:../../../../utils/udp/udp-transport"
|
|
46
48
|
}
|
|
47
49
|
}
|
package/protocol.js
CHANGED
|
@@ -21,17 +21,17 @@ export function nextSequence() {
|
|
|
21
21
|
export function getSource() {
|
|
22
22
|
return globalSource;
|
|
23
23
|
}
|
|
24
|
-
/** MAC string to 8-byte Uint8Array (6 bytes MAC + 2 padding) */
|
|
24
|
+
/** MAC string to 8-byte Uint8Array (6 bytes MAC + 2 padding). Accepts bare or colon-separated. */
|
|
25
25
|
function macToBuffer(mac) {
|
|
26
26
|
const buf = new Uint8Array(8);
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
const clean = mac.replace(/[:\-]/g, '');
|
|
28
|
+
if (clean && clean !== '000000000000') {
|
|
29
29
|
for (let i = 0; i < 6; i++)
|
|
30
|
-
buf[i] =
|
|
30
|
+
buf[i] = parseInt(clean.substring(i * 2, i * 2 + 2), 16) || 0;
|
|
31
31
|
}
|
|
32
32
|
return buf;
|
|
33
33
|
}
|
|
34
|
-
/** Uint8Array to MAC string */
|
|
34
|
+
/** Uint8Array to colon-separated lowercase MAC string */
|
|
35
35
|
function bufferToMac(buf, offset = 0) {
|
|
36
36
|
const parts = [];
|
|
37
37
|
for (let i = 0; i < 6; i++) {
|
package/transport.d.ts
CHANGED
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
* Re-export UDP transport interfaces from @bobfrankston/udp-transport
|
|
3
3
|
* LxTransport is kept as an alias for backwards compatibility
|
|
4
4
|
*/
|
|
5
|
-
export { UdpTransport, RemoteInfo } from '@bobfrankston/udp-transport';
|
|
5
|
+
export { UdpTransport, UdpTransportFactory, RemoteInfo, StateEventInfo } from '@bobfrankston/udp-transport';
|
|
6
6
|
export { UdpTransport as LxTransport } from '@bobfrankston/udp-transport';
|
|
7
7
|
//# sourceMappingURL=transport.d.ts.map
|
package/types.d.ts
CHANGED
|
@@ -108,11 +108,6 @@ export interface DeviceState {
|
|
|
108
108
|
uptime?: number;
|
|
109
109
|
downtime?: number;
|
|
110
110
|
}
|
|
111
|
-
/** Info passed with state events */
|
|
112
|
-
export interface StateEventInfo {
|
|
113
|
-
/** true if from device response, false if from peer client broadcast */
|
|
114
|
-
primary: boolean;
|
|
115
|
-
}
|
|
116
111
|
/** LIFX port */
|
|
117
112
|
export declare const LIFX_PORT = 56700;
|
|
118
113
|
/** Header size */
|