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

dt-common-device

v13.3.5

Published

A secure and robust device management library for IoT applications

Readme

dt-common-device

A comprehensive TypeScript library for device management, supporting both cloud and local device operations with advanced event handling, queue management, and audit logging.

Installation

npm install dt-common-device

Environment Variables Required

The following environment variables are REQUIRED for the library to function:

AWS Configuration

  • AWS_SECRET_ACCESS_KEY — Your AWS secret access key
  • AWS_REGION — Your AWS region
  • AWS_ACCESS_KEY_ID — Your AWS access key ID
  • EVENT_BUS_NAME — Your AWS EventBridge event bus name

Database Configuration

  • ADMIN_DB_URI — PostgreSQL database connection URI
  • MONGODB_URI — MongoDB database connection URI

Redis Configuration

  • REDIS_HOST — Redis server host
  • REDIS_PORT — Redis server port

Audit Logging

  • POSTHOG_API_KEY — Your PostHog API key
  • POSTHOG_HOST — The PostHog host URL

SQS Configuration

  • SQS_QUEUE_URL — AWS SQS queue URL (configured during initialization)

Example .env file:

# AWS Configuration
AWS_SECRET_ACCESS_KEY=your_secret_key
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=your_access_key
EVENT_BUS_NAME=your-event-bus

# Database Configuration
ADMIN_DB_URI=postgres://username:password@host:port/database
MONGODB_URI=mongodb://username:password@host:port/database

# Redis Configuration
REDIS_HOST=localhost
REDIS_PORT=6379

# Audit Logging
POSTHOG_API_KEY=your_posthog_key
POSTHOG_HOST=https://app.posthog.com

# SQS Configuration (will be set during initialization)
SQS_QUEUE_URL=https://sqs.region.amazonaws.com/account/queue-name

The library will throw clear errors if any required environment variables are missing.


Initialization (Required)

Before using any service, you must call initialize() in your main entry file with the required configuration:

import { initialize } from "dt-common-device";

// Create a logger instance
const logger = {
  info: (message: string, ...args: any[]) => console.log(message, ...args),
  warn: (message: string, ...args: any[]) => console.warn(message, ...args),
  error: (message: string, ...args: any[]) => console.error(message, ...args),
};

// Initialize the library
await initialize({
  SOURCE: "ADMIN_SERVICE", // or "ACCESS_SERVICE" or "ENERGY_SERVICE"
  SQS_QUEUE_URL: "https://sqs.region.amazonaws.com/account/queue-name",
  DEVICE_SERVICE: "https://api.example.com/device", // Optional
  ADMIN_SERVICE: "https://api.example.com/admin", // Optional
  ACCESS_SERVICE: "https://api.example.com/access", // Optional
  ENERGY_SERVICE: "https://api.example.com/energy", // Optional
  INTERNAL_EVENT_HANDLER: {
    // Your event handler implementation
    handleEvent: async (event) => {
      // Handle internal events
      console.log("Handling event:", event);
    },
  },
  LOGGER: logger,
});

Configuration Options

  • SOURCE: Required. Must be one of: "ADMIN_SERVICE", "ACCESS_SERVICE", or "ENERGY_SERVICE"
  • SQS_QUEUE_URL: Required. Your AWS SQS queue URL
  • DEVICE_SERVICE, ADMIN_SERVICE, ACCESS_SERVICE, ENERGY_SERVICE: Optional service URLs
  • INTERNAL_EVENT_HANDLER: Required. Your event handler implementation
  • LOGGER: Required. Logger instance with info, warn, and error methods

Available Services

Local Device Service

import { LocalDeviceService } from "dt-common-device";

const deviceService = new LocalDeviceService();

// Create a device
const device = await deviceService.createDevice(deviceBody);

// Get a device
const device = await deviceService.getDevice(deviceId);

// Get multiple devices
const devices = await deviceService.getDevices(deviceIds);

// Get devices by property
const propertyDevices = await deviceService.getPropertyDevices(propertyId);

// Update a device
await deviceService.updateDevice(deviceId, updateBody);

// Delete a device
await deviceService.deleteDevice(deviceId);

// State management
const state = await deviceService.getState(deviceId);
await deviceService.setState(deviceId, newState);

// Status management
const status = await deviceService.getStatus(deviceId);
await deviceService.setStatus(
  deviceId,
  newStatus,
  "heartbeat",
  "Device went offline due to network connectivity issues"
);

// Battery management
const battery = await deviceService.getBatteryLevel(deviceId);
await deviceService.setBatteryLevel(deviceId, batteryLevel, "heartbeat");

// Metadata management
const metadata = await deviceService.getMetaData(deviceId);
await deviceService.setMetaData(deviceId, metadata);

// Query operations
const devices = await deviceService.queryDevices(query);
const count = await deviceService.queryCount(query);
await deviceService.deleteDevices(query);

Local Hub Service

import { LocalHubService } from "dt-common-device";

const hubService = new LocalHubService();

// Add a hub
const hub = await hubService.addHub(hubBody);

// Get hubs
const hubs = await hubService.getHubs(hubIds);

// Get a single hub
const hub = await hubService.getHub(hubId);

// Update a hub
await hubService.updateHub(hubId, updateBody);

// Get hub status
const status = await hubService.getStatus(hubId);

// Delete a hub
await hubService.deleteHub(hubId);

// Delete multiple hubs
await hubService.deleteAllHubs(hubIds);

Local Schedule Service

import { LocalScheduleService } from "dt-common-device";

const scheduleService = new LocalScheduleService();

// Get a schedule
const schedule = await scheduleService.getSchedule(scheduleId);

// Set a schedule
await scheduleService.setSchedule(scheduleId, schedule);

// Get schedule by zone
const zoneSchedule = await scheduleService.getScheduleByZone(zoneId);

Local Connection Service

import { LocalConnectionService } from "dt-common-device";

const connectionService = new LocalConnectionService();

// Create a connection
const connection = await connectionService.createConnection({
  connectionName: "My Connection",
  connectionRefId: "ref-123",
  propertyId: "prop-456",
  connectionProvider: "Sensibo",
});

// Get a connection
const connection = await connectionService.getConnection(connectionId);

// Update a connection
await connectionService.updateConnection(connectionId, updateData);

Cloud Device Service

import { CloudDeviceService, DeviceFactory } from "dt-common-device";

const cloudService = new CloudDeviceService();
const deviceFactory = new DeviceFactory();

// Get cloud devices (must implement in your project)
// await cloudService.getDevices(connection);

// Get device using factory
const device = await deviceFactory.getDevice(deviceId);

Property Service

import { PropertyService } from "dt-common-device";

const propertyService = new PropertyService();

// Property operations (implementation specific)
// await propertyService.getProperty(propertyId);

Event System

The library includes a comprehensive event handling system:

import {
  EventHandler,
  EventProcessingService,
  DeviceEventHandler,
  EventHandlerOrchestrator,
} from "dt-common-device";

// Event handler for device operations
const eventHandler = new EventHandler();

// Device-specific event handler
const deviceEventHandler = new DeviceEventHandler();

// Event processing service
const eventProcessingService = new EventProcessingService();

// Event handler orchestrator
const orchestrator = new EventHandlerOrchestrator();

Queue System

The library provides a hybrid HTTP queue system for managing HTTP requests:

import { QueueService } from "dt-common-device";

const queueService = new QueueService();

// Make a rate-limited HTTP request
const response = await queueService.request({
  method: "GET",
  url: "https://api.example.com/data",
  headers: { "Content-Type": "application/json" },
  queueOptions: {
    connectionId: "connection-123",
    connectionProvider: "Sensibo",
    microservice: "smart-energy",
  },
});

Features

  • Rate Limiting: Automatic rate limiting per provider and connection
  • Retry Logic: Exponential backoff with configurable retry attempts
  • Audit Logging: Automatic audit logging for all requests
  • Queue Management: Redis-based queue with BullMQ
  • Error Handling: Comprehensive error handling and logging

Alert and Issue Management

import {
  AlertService,
  IssueService,
  AlertBuilder,
  IssueBuilder,
} from "dt-common-device";

// Alert service
const alertService = new AlertService();

// Issue service
const issueService = new IssueService();

// Build alerts
const alert = new AlertBuilder()
  .setTitle("Device Offline")
  .setDescription("Device has been offline for more than 24 hours")
  .setSeverity("HIGH")
  .build();

// Build issues
const issue = new IssueBuilder()
  .setTitle("Connection Failed")
  .setDescription("Failed to connect to device")
  .setPriority("HIGH")
  .build();

Graceful Shutdown

import { shutdown } from "dt-common-device";

// Gracefully shutdown the library
await shutdown();

Importing Types and Interfaces

All types and interfaces are available as named exports:

import {
  IDevice,
  IHub,
  IConnection,
  ISchedule,
  IProperty,
  IAlert,
  IIssue,
} from "dt-common-device";

Dependencies

The library requires the following major dependencies:

  • axios: HTTP client
  • bullmq: Queue management
  • dt-audit-library: Audit logging
  • dt-pub-sub: Event publishing/subscribing
  • ioredis: Redis client
  • mongoose: MongoDB ODM
  • pg: PostgreSQL client
  • typedi: Dependency injection

Notes

  • You must call initialize() before using any service. If not, you will get a runtime error.
  • You must set POSTHOG_API_KEY and POSTHOG_HOST in your environment before using any local device service.
  • You do not need to call initializeAudit()

Rate Limiting

The queue system now implements intelligent rate limiting that delays requests instead of dropping them when rate limits are exceeded.

How it works

  1. Rate Limit Check: Before processing each HTTP request, the system checks if the rate limit for the provider/connection combination has been exceeded.

  2. Delay Instead of Drop: If the rate limit is exceeded, instead of immediately failing the request, the system:

    • Calculates when the next request can be processed (after the rate limit window expires)
    • Delays the job execution by the calculated time
    • Re-checks the rate limit after the delay
    • Only fails if still rate limited after the delay
  3. Example Scenario:

    Rate Limit: 5 requests per 60 seconds
    
    Timeline:
    0s: Request 1 (processed immediately)
    10s: Request 2 (processed immediately)
    20s: Request 3 (processed immediately)
    30s: Request 4 (processed immediately)
    40s: Request 5 (processed immediately)
    45s: Request 6 (delayed by 15s, processed at 60s)
    50s: Request 7 (delayed by 10s, processed at 60s)

Configuration

Rate limits are configured per provider in src/queue/utils/rateLimit.utils.ts:

configs.set("Sensibo", {
  maxRequests: 5, // Maximum requests allowed
  windowMs: 60000, // Time window in milliseconds
  provider: "Sensibo",
});

Benefits

  • No Lost Requests: Requests are delayed rather than dropped
  • Automatic Recovery: System automatically processes delayed requests when rate limits reset
  • Better User Experience: Users don't see immediate failures due to rate limits
  • Audit Trail: All rate limit events are logged for monitoring