npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@evops/lightwaverf

v1.0.5

Published

Lightwave RF client library

Downloads

44

Readme

@evops/lightwaverf

A modern TypeScript client library for controlling LightwaveRF home automation devices

npm version License: MIT

Control your LightwaveRF smart lights, switches, and dimmers from Node.js with a clean, type-safe API. This library communicates with LightwaveRF Link Plus devices over your local network and integrates with the LightwaveRF cloud API for device configuration.

Features

  • 🎯 Type-Safe - Full TypeScript support with strict type checking
  • 🔌 Event-Driven - Real-time device state change notifications
  • 🔄 Automatic Device Discovery - Finds LightwaveRF Link devices on your network
  • 🔐 Registration Management - Handles device pairing automatically
  • Command Queueing - Built-in queue prevents command collisions
  • 🔁 Retry Logic - Automatic retry with exponential backoff on errors
  • 🐛 Debug Logging - Comprehensive debug output via debug module
  • ☁️ Cloud Integration - Fetches device configuration from LightwaveRF cloud
  • Well Tested - Comprehensive test suite with Vitest

Installation

npm install @evops/lightwaverf

Quick Start

import LightwaveRF from '@evops/lightwaverf';

// Initialize the client
const lw = new LightwaveRF({
  email: '[email protected]',
  pin: '1234',
  ip: '192.168.1.100' // Optional: Link IP (auto-discovered if omitted)
});

// Connect and ensure registration
await lw.connect();
await lw.ensureRegistration();

// Get all your devices
const devices = await lw.getDevices();
console.log('Found devices:', devices);

// Control a device
const myLight = devices.find(d => d.deviceName === 'Living Room Light');
await lw.turnOn(myLight);
await lw.dim(myLight, 50); // Set to 50% brightness
await lw.turnOff(myLight);

API Reference

Constructor

new LightwaveRF(config: LightwaveRFConfiguration)

Configuration Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | email | string | - | Your LightwaveRF account email | | pin | string | - | Your LightwaveRF account PIN | | ip | string | 255.255.255.255 | Link device IP (defaults to broadcast for auto-discovery) | | timeout | number | 1000 | Command timeout in milliseconds |

Methods

Device Control

turnOn(device: ILightwaveDevice): Promise<void>

Turns a device on.

await lw.turnOn({ roomId: 1, deviceId: 1, roomName: 'Living Room', deviceName: 'Light' });
turnOff(device: ILightwaveDevice): Promise<void>

Turns a device off.

await lw.turnOff(myLight);
dim(device: ILightwaveDevice, percentage: number): Promise<void>

Dims a device to the specified percentage (0-100).

await lw.dim(myLight, 75); // Set to 75% brightness

Device Management

getDevices(): Promise<LightwaveDevice[]>

Retrieves all devices from your LightwaveRF cloud account.

const devices = await lw.getDevices();
devices.forEach(device => {
  console.log(`${device.roomName} - ${device.deviceName} (${device.deviceType})`);
});

Connection & Registration

connect(): Promise<void>

Connects to the LightwaveRF Link device on your local network.

await lw.connect();
isRegistered(): Promise<boolean>

Checks if the client is registered with the Link device.

const registered = await lw.isRegistered();
if (!registered) {
  console.log('Please press the button on your Link device to register');
}
ensureRegistration(): Promise<void>

Ensures the client is registered with the Link. If not registered, enters pairing mode. You'll need to press the pairing button on your Link device.

await lw.ensureRegistration();

Device Information (Read-only Properties)

console.log('Serial:', lw.serial);
console.log('MAC Address:', lw.mac);
console.log('Uptime:', lw.uptime);
console.log('Model:', lw.model);
console.log('Firmware Version:', lw.version);

Events

The client extends EventEmitter and emits the following events:

deviceTurnedOn

Emitted when a device is turned on (including via physical switches or other apps).

lw.on('deviceTurnedOn', (roomId: number, deviceId: number) => {
  console.log(`Device ${deviceId} in room ${roomId} was turned on`);
});

deviceTurnedOff

Emitted when a device is turned off.

lw.on('deviceTurnedOff', (roomId: number, deviceId: number) => {
  console.log(`Device ${deviceId} in room ${roomId} was turned off`);
});

deviceDimmed

Emitted when a device is dimmed to a specific level.

lw.on('deviceDimmed', (roomId: number, deviceId: number, percentage: number) => {
  console.log(`Device ${deviceId} in room ${roomId} dimmed to ${percentage}%`);
});

Types

ILightwaveDevice

interface ILightwaveDevice {
  roomId: number;
  deviceId: number;
  roomName: string;
  deviceName: string;
  deviceType: string;
}

LightwaveDeviceType

enum LightwaveDeviceType {
  Dimmer = "D",
  OnOff = "O"
}

LightwaveDevice

A class representing a physical LightwaveRF device. Returned by getDevices().

class LightwaveDevice {
  roomId: number;
  deviceId: number;
  roomName: string;
  deviceName: string;
  deviceType: LightwaveDeviceType;
}

Examples

Basic Device Control

import LightwaveRF from '@evops/lightwaverf';

const lw = new LightwaveRF({
  email: '[email protected]',
  pin: '1234'
});

await lw.connect();
await lw.ensureRegistration();

// Turn on all devices
const devices = await lw.getDevices();
for (const device of devices) {
  await lw.turnOn(device);
}

Scene Control with Dimming

// Create a movie night scene
async function movieNightScene(lw, devices) {
  const ceilingLight = devices.find(d => d.deviceName === 'Ceiling Light');
  const lampLeft = devices.find(d => d.deviceName === 'Lamp Left');
  const lampRight = devices.find(d => d.deviceName === 'Lamp Right');

  await lw.turnOff(ceilingLight);
  await lw.dim(lampLeft, 30);
  await lw.dim(lampRight, 30);
}

await movieNightScene(lw, await lw.getDevices());

Event Monitoring

// Monitor all device state changes
lw.on('deviceTurnedOn', (roomId, deviceId) => {
  console.log(`[ON]  Room ${roomId}, Device ${deviceId}`);
});

lw.on('deviceTurnedOff', (roomId, deviceId) => {
  console.log(`[OFF] Room ${roomId}, Device ${deviceId}`);
});

lw.on('deviceDimmed', (roomId, deviceId, percentage) => {
  console.log(`[DIM] Room ${roomId}, Device ${deviceId} -> ${percentage}%`);
});

Control by Room and Device ID

If you already know your room and device IDs, you can control devices directly without fetching from the cloud:

await lw.turnOn({
  roomId: 1,
  deviceId: 2,
  roomName: 'Living Room',
  deviceName: 'Light'
});

Error Handling

try {
  await lw.connect();
  await lw.ensureRegistration();

  const devices = await lw.getDevices();
  await lw.turnOn(devices[0]);
} catch (error) {
  console.error('Error controlling devices:', error);
}

Enable Debug Logging

Use the debug module to see detailed logging:

DEBUG=lightwave* node your-script.js

This will show all UDP communication, command queue operations, and API calls.

How It Works

Architecture

  1. LightwaveRF Client (Main API) - High-level interface for device control and management
  2. LightwaveRFClient - Low-level UDP client handling communication with Link devices
  3. LightwaveAccount - Cloud API integration for device configuration
  4. Message Processors - Parse JSON and text protocol responses
  5. Queue System - Manages command transactions and prevents conflicts

Communication Protocol

The library communicates with LightwaveRF Link devices using:

  • Protocol: UDP
  • Ports: Sends on 9760, receives on 9761
  • Rate Limiting: 125ms delay between commands
  • Transaction-Based: Each command gets a unique transaction ID
  • Response Timeout: 5 seconds (configurable)
  • Format: Supports both JSON (*!{...}) and text responses

Device Discovery

When no IP is specified (or 255.255.255.255 is used), the library broadcasts on the local network to automatically discover LightwaveRF Link devices.

Requirements

  • Node.js 14 or higher
  • LightwaveRF Link or Link Plus device
  • LightwaveRF account (for device configuration)
  • Local network access to the Link device

Troubleshooting

Connection Issues

Problem: Cannot connect to Link device

Solution:

  • Ensure your Link device is powered on and connected to the same network
  • Try specifying the Link IP address explicitly in the config
  • Check your firewall allows UDP traffic on ports 9760/9761

Registration Issues

Problem: ensureRegistration() hangs or fails

Solution:

  • Press and release the pairing button on your Link device when prompted
  • The Link button should flash during pairing mode
  • Registration is usually required only once per client

Device Control Not Working

Problem: Commands don't affect devices

Solution:

  • Verify you're registered with await lw.isRegistered()
  • Check device IDs match your actual device configuration
  • Enable debug logging to see command/response details
  • Ensure devices are paired with your Link in the LightwaveRF app

Cloud API Issues

Problem: getDevices() fails

Solution:

  • Verify your email and PIN are correct
  • Check your internet connection (cloud API requires internet)
  • Ensure you have devices configured in your LightwaveRF account

Migration from 0.x to 1.0

Version 1.0 is a complete TypeScript rewrite with breaking changes. See CHANGELOG.md for details.

Key Changes

  • ✅ Public API remains compatible
  • ⚠️ Output directory changed from dist to .dist
  • ⚠️ Internal files renamed (only affects direct imports)
  • ⚠️ CLI removed (use library API directly)
  • ⚠️ Modern ES2024 output with strict TypeScript

Development

# Install dependencies
npm install

# Run tests
npm test

# Build TypeScript
npm run prepublish

Testing

The library includes comprehensive tests using Vitest with HTTP request recording/replay:

npm test

Tests use fetch-vcr to record API interactions, making them fast and reliable.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

MIT License - see LICENSE file for details

Credits

Originally based on node-lightwaverf by Ollie Parsley.

Rewritten and maintained by Stanislaw Wozniak.

Related Projects

Support


Made with ⚡ by the community