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

@alteriom/mqtt-schema

v0.8.0

Published

Alteriom MQTT v1 schemas, TypeScript types, and validation helpers for web integration

Readme

@alteriom/mqtt-schema

Metadata Compliance OTA Manifest Validation Schema Verify npm version npm downloads license npm total downloads node version peer ajv latest tag bundle size

Alteriom MQTT v1 JSON Schemas, TypeScript types, and production‑ready validation helpers for integrating firmware MQTT payloads into web or backend services.

Why this exists

Firmware emits structured MQTT payloads that must remain tightly aligned with web, analytics, and gateway logic. This package is the single source of truth for:

  • Canonical, versioned JSON Schemas (schema_version: 1 series)
  • Embedded (tree‑shakeable) schema objects — no runtime file I/O
  • Precompiled Ajv validators (fast + consistent across CJS / ESM)
  • TypeScript interfaces & type guards generated from the same source schema set
  • Message classification helper that infers the schema kind heuristically
  • Forward‑compatible design: unknown extra properties are ignored unless explicitly constrained

Features

  • Dual build: CommonJS + ESM (Node 16+ / bundlers)
  • Zero configuration: just import and validate
  • Helpful error paths (JSON Pointer style)
  • Lightweight (Ajv peer dependency, schemas embedded)
  • Ships original schema JSON files (optional consumption)
  • NEW in v0.8.0: ⚠️ BREAKING: Gateway code realignment (300→305, 301→306) with automatic legacy translation
  • NEW in v0.8.0: Unified device schemas (10x range) for sensor/gateway/bridge/hybrid deployments
  • NEW in v0.8.0: HTTP transport support via transport_metadata for REST API integration
  • NEW in v0.8.0: Bridge management schemas for painlessMesh v1.8.0+ (5 new message types)
  • NEW in v0.7.3: Message batching for 50-90% protocol overhead reduction
  • NEW in v0.7.3: Compression support for 60-80% bandwidth savings (gzip, zlib, brotli, deflate)
  • NEW in v0.7.3: Comprehensive example repository (9 examples, 4 categories)
  • NEW in v0.7.3: Professional code quality tooling (ESLint, Prettier, Husky)
  • NEW in v0.7.3: 87% test coverage with 134 tests (28 unit, 12 integration, 68 fixtures)
  • NEW in v0.7.1: Message type codes for significantly faster classification and standardized routing
  • NEW in v0.7.1: PainlessMesh bridge schema for mesh protocol integration
  • NEW in v0.7.0: Best-in-class OTA management with security, rollback, and delta updates
  • NEW in v0.6.0: Enhanced location/geolocation support for asset tracking
  • NEW in v0.6.0: Extended sensor metadata (accuracy, calibration, operational range)
  • NEW in v0.6.0: Comprehensive gateway health metrics (storage, network, errors)

Documentation

📚 GitHub Wiki - Comprehensive API documentation, schema references, validation rules, and guides

Note: If the wiki appears empty, see WIKI_SETUP.md for setup instructions. The wiki is automatically generated and synced from the repository.

Installation

npm install @alteriom/mqtt-schema ajv ajv-formats

Support & Compatibility: Node 18+ tested; Node 20 primary. Dual CJS/ESM builds.

Quick Start

Fast Classification with Type Codes (v0.7.1+)

For optimal performance, include the optional message_type field:

import { classifyAndValidate, MessageTypeCodes } from '@alteriom/mqtt-schema';

const payload = {
  schema_version: 1,
  message_type: MessageTypeCodes.SENSOR_DATA, // 200 - enables 90% faster classification
  device_id: 'SN001',
  device_type: 'sensor',
  timestamp: new Date().toISOString(),
  firmware_version: 'SN 2.1.5',
  sensors: {
    temperature: { value: 22.5, unit: 'C' }
  }
};

const { kind, result } = classifyAndValidate(payload);
// Fast path: O(1) lookup vs O(n) heuristics

Validate a JSON payload (object already parsed):

import { validators } from '@alteriom/mqtt-schema';

const payload = JSON.parse(rawMqttString);
const result = validators.sensorData(payload);
if (!result.valid) {
  console.error('Invalid sensor data', result.errors);
}

Classify and validate automatically:

import { classifyAndValidate } from '@alteriom/mqtt-schema';

const { kind, result } = classifyAndValidate(payload);
if (result.valid) {
  console.log('Message kind:', kind);
} else {
  console.warn('Validation errors', result.errors);
}

Use strong TypeScript types after classification:

import { classifyAndValidate, isSensorDataMessage, SensorDataMessage } from '@alteriom/mqtt-schema';

const { result } = classifyAndValidate(payload);
if (result.valid && isSensorDataMessage(payload)) {
  const data: SensorDataMessage = payload;
  Object.entries(data.sensors).forEach(([name, s]) => {
    console.log(name, s.value, s.unit);
  });
}

Access raw schema JSON (if you need to introspect or power form generation):

import envelopeSchema from '@alteriom/mqtt-schema/schemas/envelope.schema.json';

Command & Control (v0.5.0+)

Send commands to devices and receive responses with correlation tracking:

import { validators, isCommandMessage, isCommandResponseMessage } from '@alteriom/mqtt-schema';

// Create a command message
const command = {
  schema_version: 1,
  device_id: 'ALT-441D64F804A0',
  device_type: 'sensor',
  timestamp: new Date().toISOString(),
  firmware_version: 'WEB 1.0.0',
  event: 'command',
  command: 'read_sensors',
  correlation_id: `cmd-${Date.now()}-001`,
  parameters: {
    immediate: true,
    sensors: ['temperature', 'humidity']
  },
  priority: 'high'
};

// Validate before sending
const cmdResult = validators.command(command);
if (cmdResult.valid) {
  // Publish to MQTT topic: alteriom/nodes/{device_id}/commands
  mqttClient.publish(`alteriom/nodes/${command.device_id}/commands`, JSON.stringify(command));
}

// Handle response from device
mqttClient.subscribe(`alteriom/nodes/${command.device_id}/responses`, (message) => {
  const response = JSON.parse(message);
  const respResult = validators.commandResponse(response);
  
  if (respResult.valid && isCommandResponseMessage(response)) {
    if (response.correlation_id === command.correlation_id) {
      if (response.success) {
        console.log('Command succeeded:', response.result);
        console.log(`Latency: ${response.latency_ms}ms`);
      } else {
        console.error(`Command failed: ${response.error_code} - ${response.message}`);
      }
    }
  }
});

Command Pattern Features:

  • Event-based discrimination (event: "command" and event: "command_response")
  • Correlation IDs for request/response tracking
  • Command name validation (lowercase snake_case)
  • Flexible parameters object for command-specific data
  • Priority field for queue management
  • Success boolean and error codes in responses
  • Latency tracking for performance monitoring

PainlessMesh Protocol Bridge (v0.7.1+)

Standardize MQTT-to-mesh protocol bridging for seamless integration with ESP32/ESP8266 mesh networks:

import { validators, isMeshBridgeMessage } from '@alteriom/mqtt-schema';

// Gateway bridges painlessMesh message to MQTT
const meshBridge = {
  schema_version: 1,
  message_type: 603, // MESH_BRIDGE
  device_id: 'GW-MESH-01',
  device_type: 'gateway',
  timestamp: new Date().toISOString(),
  firmware_version: 'GW 3.2.0',
  event: 'mesh_bridge',
  mesh_protocol: 'painlessMesh',
  mesh_message: {
    from_node_id: 123456789,  // painlessMesh uint32 node ID
    to_node_id: 987654321,
    mesh_type: 8,              // painlessMesh SINGLE message
    mesh_type_name: 'SINGLE',
    payload_decoded: {
      // Decoded MQTT v1 message from mesh node
      schema_version: 1,
      device_id: 'MESH-NODE-123456789',
      device_type: 'sensor',
      timestamp: '2025-10-23T20:30:00.000Z',
      firmware_version: 'SN 2.0.0',
      sensors: {
        temperature: { value: 22.5, unit: 'C' }
      }
    },
    rssi: -72,        // Signal strength
    hop_count: 2      // Hops from source to gateway
  }
};

const result = validators.meshBridge(meshBridge);
if (result.valid && isMeshBridgeMessage(meshBridge)) {
  // Process mesh message with full context
  console.log(`Mesh message from node ${meshBridge.mesh_message.from_node_id}`);
  console.log(`Signal: ${meshBridge.mesh_message.rssi} dBm, Hops: ${meshBridge.mesh_message.hop_count}`);
  
  if (meshBridge.mesh_message.payload_decoded) {
    // Process decoded MQTT v1 message
    const innerMessage = meshBridge.mesh_message.payload_decoded;
    console.log('Decoded sensor data:', innerMessage.sensors);
  }
}

Mesh Bridge Features:

  • Multi-Protocol Support: painlessMesh, ESP-NOW, BLE Mesh, Thread, Zigbee
  • Dual Payload Format: Raw (base64/hex) and decoded MQTT v1 messages
  • Network Observability: RSSI, hop count, mesh timestamps
  • Gateway Context: Gateway node ID and mesh network identifier
  • Standardized Translation: Consistent format across different mesh protocols

Use Cases:

  • Bridge ESP32 painlessMesh networks to cloud MQTT
  • Integrate ESP-NOW devices without direct WiFi
  • Heterogeneous mesh gateway (multiple mesh protocols)
  • Mesh network debugging and visualization
  • Low-power mesh sensor networks with cloud backend

PainlessMesh Integration Pattern:

// ESP32 Gateway Firmware (C++)
void onMeshReceive(uint32_t from, String &msg) {
  // Wrap painlessMesh message in MQTT envelope
  StaticJsonDocument<1024> bridgeMsg;
  bridgeMsg["schema_version"] = 1;
  bridgeMsg["message_type"] = 603;
  bridgeMsg["device_id"] = "GW-MESH-01";
  bridgeMsg["device_type"] = "gateway";
  bridgeMsg["event"] = "mesh_bridge";
  bridgeMsg["mesh_protocol"] = "painlessMesh";
  
  JsonObject meshMsg = bridgeMsg.createNestedObject("mesh_message");
  meshMsg["from_node_id"] = from;
  meshMsg["to_node_id"] = mesh.getNodeId();
  meshMsg["raw_payload"] = base64::encode(msg);
  meshMsg["rssi"] = mesh.getRssi(from); // If available
  
  // Try to decode as MQTT v1 message
  StaticJsonDocument<512> decoded;
  if (deserializeJson(decoded, msg) == DeserializationError::Ok) {
    meshMsg["payload_decoded"] = decoded;
  }
  
  // Publish to MQTT broker
  String bridgeJson;
  serializeJson(bridgeMsg, bridgeJson);
  mqttClient.publish("alteriom/mesh/bridge", bridgeJson);
}

Enhanced Location & Environment Tracking (v0.6.0+)

Track device location and deployment context for asset management and map-based visualization:

import { validators, isSensorDataMessage } from '@alteriom/mqtt-schema';

const sensorData = {
  schema_version: 1,
  device_id: 'SN456',
  device_type: 'sensor',
  timestamp: new Date().toISOString(),
  firmware_version: 'SN 2.1.0',
  // Standardized location for map visualization
  location: {
    latitude: 43.6532,
    longitude: -79.3832,
    altitude: 76.5,
    accuracy_m: 10.0,
    zone: 'warehouse_A',
    description: 'Shelf 3, Row B'
  },
  // Deployment context
  environment: {
    deployment_type: 'indoor',
    power_source: 'battery',
    expected_battery_life_days: 365
  },
  sensors: {
    temperature: {
      value: 22.3,
      unit: 'C',
      // Enhanced sensor metadata
      timestamp: '2025-10-19T20:59:58.000Z',
      accuracy: 0.5,
      last_calibration: '2025-01-15',
      error_margin_pct: 2.0,
      operational_range: { min: -40, max: 85 },
      quality_score: 0.95
    }
  },
  battery_level: 78,
  signal_strength: -65
};

const result = validators.sensorData(sensorData);
if (result.valid && isSensorDataMessage(sensorData)) {
  // Display on map using location data
  displayOnMap(sensorData.location.latitude, sensorData.location.longitude);
  
  // Show sensor health based on metadata
  if (sensorData.sensors.temperature.accuracy) {
    console.log(`Temperature accuracy: ±${sensorData.sensors.temperature.accuracy}${sensorData.sensors.temperature.unit}`);
  }
  
  // Check calibration status
  const lastCal = new Date(sensorData.sensors.temperature.last_calibration);
  const daysSinceCalibration = (Date.now() - lastCal.getTime()) / (1000 * 60 * 60 * 24);
  if (daysSinceCalibration > 365) {
    console.warn('Sensor calibration overdue');
  }
}

Location & Environment Features:

  • GPS coordinates (latitude, longitude, altitude) with accuracy tracking
  • Zone-based organization (warehouses, floors, rooms)
  • Human-readable location descriptions
  • Deployment type tracking (indoor/outdoor/mobile)
  • Power source information for battery management
  • Per-sensor timestamps for async polling scenarios
  • Sensor accuracy and calibration tracking
  • Operational range validation support

Enhanced Gateway Metrics (v0.6.0+)

Comprehensive system health monitoring for gateways:

import { validators, isGatewayMetricsMessage } from '@alteriom/mqtt-schema';

const metrics = {
  schema_version: 1,
  device_id: 'GW002',
  device_type: 'gateway',
  timestamp: new Date().toISOString(),
  firmware_version: 'GW 1.4.0',
  metrics: {
    uptime_s: 86400,
    cpu_usage_pct: 15.3,
    memory_usage_pct: 42.7,
    temperature_c: 45.2,
    // Enhanced storage metrics
    storage_usage_pct: 45.2,
    storage_total_mb: 512,
    storage_free_mb: 280.5,
    // Network bandwidth tracking
    network_rx_kbps: 125.4,
    network_tx_kbps: 89.3,
    active_connections: 5,
    // System health indicators
    error_count_24h: 3,
    warning_count_24h: 12,
    restart_count: 2,
    last_restart_reason: 'firmware_update',
    // Mesh network metrics
    connected_devices: 12,
    mesh_nodes: 8,
    packet_loss_pct: 0.5
  }
};

const result = validators.gatewayMetrics(metrics);
if (result.valid && isGatewayMetricsMessage(metrics)) {
  // Storage monitoring
  if (metrics.metrics.storage_usage_pct > 80) {
    console.warn('Storage usage critical:', metrics.metrics.storage_usage_pct);
  }
  
  // Network health
  const totalBandwidth = metrics.metrics.network_rx_kbps + metrics.metrics.network_tx_kbps;
  console.log(`Total bandwidth: ${totalBandwidth.toFixed(1)} kbps`);
  
  // Error trend analysis
  if (metrics.metrics.error_count_24h > 10) {
    console.error('High error rate detected:', metrics.metrics.error_count_24h);
  }
  
  // Restart tracking
  console.log(`Last restart: ${metrics.metrics.last_restart_reason}`);
  console.log(`Total restarts: ${metrics.metrics.restart_count}`);
}

Enhanced Gateway Metrics Features:

  • Storage usage tracking (percentage, total, free space)
  • Network bandwidth monitoring (RX/TX rates)
  • Active connection counting
  • Error and warning counters (24-hour rolling window)
  • Restart tracking with reason codes
  • All metrics are optional for gradual firmware adoption

OTA Firmware Management (v0.7.0+)

Comprehensive best-in-class OTA solution based on 2024 industry standards.

OTA Manifest Schema

The package includes OTA firmware manifest schema with both rich and minimal formats, enhanced with enterprise-grade features.

Preferred: Stable alias import (v0.3.1+):

import otaManifestSchema from '@alteriom/mqtt-schema/ota-manifest';
import { OtaManifest, isRichManifest } from '@alteriom/mqtt-schema/types/ota-manifest';

Legacy: Deep path import (still supported):

import otaManifestSchema from '@alteriom/mqtt-schema/schemas/ota/ota-manifest.schema.json';

Usage example:

import Ajv from 'ajv';
import addFormats from 'ajv-formats';
import otaManifestSchema from '@alteriom/mqtt-schema/ota-manifest';
import { OtaManifest } from '@alteriom/mqtt-schema/types/ota-manifest';

const ajv = new Ajv({ allErrors: true, strict: false });
addFormats(ajv);
const validate = ajv.compile<OtaManifest>(otaManifestSchema as any);

const manifest: OtaManifest = JSON.parse(manifestJson);
if (!validate(manifest)) {
  console.error('Invalid OTA manifest:', validate.errors);
}

Supported formats:

  • Rich manifest: environment + branch + manifests object
  • Minimal environment map: environment → channels mapping
  • Chunk variants: structured objects or SHA256 array

Enhanced OTA Features (v0.7.0+)

Security & Authenticity:

const manifest = {
  environment: "universal-sensor",
  branch: "main",
  manifests: {
    prod: {
      build_type: "prod",
      file: "firmware-v2.0.0.bin",
      size: 456789,
      sha256: "a1b2c3...",
      firmware_version: "2.0.0",
      built: "2025-10-19T12:00:00Z",
      ota_url: "https://firmware.example.com/v2.0.0.bin",
      
      // Digital signature for authenticity
      signature: "MEUCIQDx...",
      signature_algorithm: "ECDSA-SHA256",
      signing_key_id: "prod-signing-key-2025",
      
      // Version constraints
      min_version: "1.5.0",        // Minimum version to upgrade from
      max_version: "1.9.99",       // Prevent downgrades
      
      // Release management
      release_notes_url: "https://docs.example.com/v2.0.0",
      criticality: "high",          // low | medium | high | critical
      mandatory: true,              // Must be installed
      
      // Staged rollout
      rollout_percentage: 25,       // Start with 25% of fleet
      rollout_target_groups: ["beta-testers", "early-adopters"],
      
      // Delta updates (60-90% bandwidth reduction)
      delta_from_version: "1.9.0",
      delta_patch_url: "https://firmware.example.com/patches/1.9.0-to-2.0.0.patch",
      delta_patch_size: 45678,
      delta_patch_sha256: "c3d4e5..."
    }
  }
};

Firmware Update Status Tracking:

import { validators, isFirmwareStatusMessage } from '@alteriom/mqtt-schema';

// Enhanced status tracking
const status = {
  schema_version: 1,
  device_id: "SN789",
  device_type: "sensor",
  timestamp: new Date().toISOString(),
  firmware_version: "2.0.0",
  
  status: "downloading",           // New: rolled_back, rollback_pending, rollback_failed
  progress_pct: 42,
  
  // Progress details
  download_speed_kbps: 125.5,
  bytes_downloaded: 196608,
  bytes_total: 456789,
  eta_seconds: 28,
  
  // Rollback support
  rollback_available: true,
  previous_version: "1.9.0",
  
  // Security verification
  update_type: "delta",            // full | delta | patch
  signature_verified: true,
  checksum_verified: true,
  
  // Operational context
  battery_level_pct: 85,
  free_space_kb: 2048,
  retry_count: 0
};

const result = validators.firmwareStatus(status);
if (result.valid) {
  console.log(`Download progress: ${status.progress_pct}% at ${status.download_speed_kbps} kbps`);
  console.log(`ETA: ${status.eta_seconds} seconds`);
}

OTA Best Practices:

  • Security: Always use digital signatures for production firmware
  • Rollback: Maintain backup partition for automatic rollback on failures
  • Delta Updates: Use delta patches for bandwidth-constrained deployments (60-90% reduction)
  • Staged Rollout: Start with 5-10% rollout, monitor, then expand gradually
  • Version Control: Use min_version to prevent upgrades from incompatible versions
  • Criticality: Mark security patches as "critical" with mandatory: true

See docs/OTA_MANIFEST.md for comprehensive guide and best practices.

API Surface

import { validators, validateMessage, classifyAndValidate } from '@alteriom/mqtt-schema';

// 1. Direct validator by message kind
validators.sensorData(payload); // => { valid: boolean; errors?: string[] }

// 2. Generic function
validateMessage('sensorData', payload);

// 3. Classify unknown payload then validate
const { kind, result } = classifyAndValidate(payload);

// 4. Type guards (when available)
// if (isSensorDataMessage(payload)) { ... }

Validation result format:

interface ValidationResult {
  valid: boolean;
  errors?: string[]; // Each item contains instancePath + message
}

Performance Notes

All Ajv validator functions are compiled once at module load. For typical web usage (tens to hundreds of validations per page/session) this is faster and simpler than on‑demand compilation. If you need custom Ajv options (e.g., different formats), open an issue—an override hook can be added without breaking changes.

Embedded Schemas

schema_data.ts is auto‑generated during build. This avoids dynamic require() / import of JSON and works cleanly in both Node ESM and bundlers without JSON import assertions. The original JSON files are still published under schemas/ for tooling or documentation pipelines.

Device Configuration Management (v0.7.1+)

Unified configuration management for both sensors and gateways, supporting remote configuration without firmware reflashing:

import { validators, isDeviceConfigMessage, MessageTypeCodes } from '@alteriom/mqtt-schema';

// Configuration update request (from backend to device)
const configUpdate = {
  schema_version: 1,
  message_type: MessageTypeCodes.DEVICE_CONFIG, // 700
  device_id: 'SN001',
  device_type: 'sensor',
  timestamp: new Date().toISOString(),
  firmware_version: 'WEB 1.0.0',
  event: 'config_update',
  configuration: {
    sampling_interval_ms: 60000,
    power_mode: 'low_power',
    ota_config: {
      auto_update: true,
      update_channel: 'stable',
      update_check_interval_h: 24
    },
    alert_thresholds: {
      temperature: {
        min: -10,
        max: 50,
        enabled: true
      }
    }
  },
  modified_by: '[email protected]'
};

const result = validators.deviceConfig(configUpdate);
if (result.valid) {
  // Publish to device: alteriom/nodes/{device_id}/config
  mqttClient.publish(`alteriom/nodes/${configUpdate.device_id}/config`, JSON.stringify(configUpdate));
}

// Configuration snapshot (from device to backend)
mqttClient.subscribe('alteriom/nodes/+/config/snapshot', (message) => {
  const snapshot = JSON.parse(message);
  
  if (isDeviceConfigMessage(snapshot) && snapshot.event === 'config_snapshot') {
    // Store configuration for audit trail
    console.log('Device config:', snapshot.device_id);
    console.log('Power mode:', snapshot.configuration.power_mode);
    console.log('OTA settings:', snapshot.configuration.ota_config);
    
    // Configuration version tracking
    if (snapshot.config_version) {
      console.log('Config version:', snapshot.config_version);
      console.log('Last modified:', snapshot.last_modified);
    }
  }
});

Unified Configuration Standards:

Both sensors and gateways support consistent management:

| Feature | Sensors | Gateways | Description | |---------|---------|----------|-------------| | OTA Configuration | ✅ | ✅ | Auto-update, channels, intervals | | Network Settings | ✅ | ✅ | WiFi, mesh, MQTT configuration | | Power Management | ✅ | ✅ | Power modes, sleep duration | | Reporting Intervals | ✅ | ✅ | Sampling and reporting intervals | | Log Levels | ✅ | ✅ | Debug, info, warn, error | | Time Sync | ✅ | ✅ | Timezone, NTP server | | Alert Thresholds | ✅ | ⚠️ | Sensor-specific thresholds | | Calibration | ✅ | ⚠️ | Sensor offset calibration |

Configuration Events:

  • config_snapshot: Device reports current configuration state
  • config_update: Backend requests configuration changes
  • config_request: Backend queries current configuration

Key Benefits:

  • Remote configuration without firmware updates
  • Configuration backup and restore
  • Audit trail with version tracking
  • Bulk configuration deployment
  • Standardized across device types

Message Type Codes (v0.8.0+)

For performance optimization and standardized routing, use the optional message_type field:

🆕 Unified Device Codes (v0.8.0+)

| Code | Constant | Message Type | Category | Description | |------|----------|--------------|----------|-------------| | 101 | DEVICE_DATA | device_data | unified | Unified telemetry for all device types (sensor/gateway/bridge/hybrid) | | 102 | DEVICE_HEARTBEAT | device_heartbeat | unified | Unified presence/health check (all device types) | | 103 | DEVICE_STATUS | device_status | unified | Unified status change notification (all device types) | | 104 | DEVICE_INFO | device_info | unified | Unified identification and capabilities (all device types) | | 105 | DEVICE_METRICS | device_metrics | unified | Unified health and performance metrics (all device types) |

Sensor-Specific Codes

| Code | Constant | Message Type | Category | Description | |------|----------|--------------|----------|-------------| | 200 | SENSOR_DATA | sensor_data | telemetry | Sensor telemetry readings | | 201 | SENSOR_HEARTBEAT | sensor_heartbeat | telemetry | Sensor presence/health | | 202 | SENSOR_STATUS | sensor_status | telemetry | Sensor status change | | 203 | SENSOR_INFO | sensor_info | telemetry | Sensor identification and capabilities (v0.7.2+) | | 204 | SENSOR_METRICS | sensor_metrics | telemetry | Sensor health and performance metrics (v0.7.2+) |

Gateway-Specific Codes

| Code | Constant | Message Type | Category | Description | |------|----------|--------------|----------|-------------| | 302 | GATEWAY_DATA | gateway_data | gateway | Gateway telemetry readings (v0.7.2+) | | 303 | GATEWAY_HEARTBEAT | gateway_heartbeat | gateway | Gateway presence/health check (v0.7.2+) | | 304 | GATEWAY_STATUS | gateway_status | gateway | Gateway status change notification (v0.7.2+) | | 305 | GATEWAY_INFO | gateway_info | gateway | Gateway identification ⚠️ BREAKING v0.8.0: was 300 | | 306 | GATEWAY_METRICS | gateway_metrics | gateway | Gateway health metrics ⚠️ BREAKING v0.8.0: was 301 |

⚠️ BREAKING CHANGES in v0.8.0: Gateway codes 300 (info) and 301 (metrics) have been realigned to 305 and 306 for consistency. Legacy codes 300 and 301 are automatically translated during a 6-month migration period. See Migration Guide below.

Command & Control

| Code | Constant | Message Type | Category | Description | |------|----------|--------------|----------|-------------| | 400 | COMMAND | command | control | Device control command | | 401 | COMMAND_RESPONSE | command_response | control | Command execution result | | 402 | CONTROL_RESPONSE | control_response | control | Legacy control response (deprecated) |

Firmware & OTA

| Code | Constant | Message Type | Category | Description | |------|----------|--------------|----------|-------------| | 500 | FIRMWARE_STATUS | firmware_status | ota | Firmware update status (enhanced v0.7.2+) |

Mesh Network

| Code | Constant | Message Type | Category | Description | |------|----------|--------------|----------|-------------| | 600 | MESH_NODE_LIST | mesh_node_list | mesh | Mesh node inventory | | 601 | MESH_TOPOLOGY | mesh_topology | mesh | Mesh network topology | | 602 | MESH_ALERT | mesh_alert | mesh | Mesh network alert | | 603 | MESH_BRIDGE | mesh_bridge | mesh | Mesh protocol bridge (v0.7.1+) | | 604 | MESH_STATUS | mesh_status | mesh | Mesh network health status (v0.7.2+) | | 605 | MESH_METRICS | mesh_metrics | mesh | Mesh network performance metrics (v0.7.2+) |

Bridge Management (v0.8.0+)

| Code | Constant | Message Type | Category | Description | |------|----------|--------------|----------|-------------| | 610 | BRIDGE_STATUS | bridge_status | bridge | Bridge health and connectivity broadcast | | 611 | BRIDGE_ELECTION | bridge_election | bridge | RSSI-based bridge election candidacy | | 612 | BRIDGE_TAKEOVER | bridge_takeover | bridge | Bridge role takeover announcement | | 613 | BRIDGE_COORDINATION | bridge_coordination | bridge | Multi-bridge coordination and load balancing | | 614 | TIME_SYNC_NTP | time_sync_ntp | bridge | Bridge-to-mesh NTP time distribution |

Configuration & Efficiency

| Code | Constant | Message Type | Category | Description | |------|----------|--------------|----------|-------------| | 700 | DEVICE_CONFIG | device_config | config | Device configuration management (v0.7.1+) | | 800 | BATCH_ENVELOPE | batch_envelope | efficiency | Message batching for 50-90% protocol overhead reduction (v0.7.3+) | | 810 | COMPRESSED_ENVELOPE | compressed_envelope | efficiency | Compressed message envelope (v0.7.3+) |

Benefits

  • Significantly Faster: O(1) lookup vs O(n) heuristic matching (avoids 12+ conditional checks)
  • Protocol Alignment: Compatible with CoAP and MQTT-SN numeric type systems
  • Clear Intent: Explicit message type declaration
  • Efficient Routing: Switch-case routing in backend systems
  • Backward Compatible: Falls back to heuristics if omitted

Usage

import { MessageTypeCodes } from '@alteriom/mqtt-schema';

const message = {
  schema_version: 1,
  message_type: MessageTypeCodes.SENSOR_DATA, // 200
  // ... rest of message
};

v0.8 Migration Guide

Breaking Changes:

  • GATEWAY_INFO: Code 300305
  • GATEWAY_METRICS: Code 301306

Migration Timeline (6 months):

  1. Phase 1 (Months 1-3): Both old and new codes accepted. Library automatically translates 300→305 and 301→306.
  2. Phase 2 (Months 4-6): Deprecation warnings logged for legacy codes.
  3. Phase 3 (After 6 months): Legacy codes 300 and 301 rejected.

Action Required:

// ❌ Old code (deprecated in v0.8.0)
const message = {
  message_type: 300, // gateway_info
  // ...
};

// ✅ New code (v0.8.0+)
const message = {
  message_type: MessageTypeCodes.GATEWAY_INFO, // 305
  // ...
};

// ✅ Better: Use unified device schemas (v0.8.0+)
const message = {
  message_type: MessageTypeCodes.DEVICE_INFO, // 104
  device_role: 'gateway', // Explicit role indicator
  // ...
};

Legacy Code Translation:

The library includes LEGACY_CODE_MAP for automatic translation:

import { LEGACY_CODE_MAP } from '@alteriom/mqtt-schema';

console.log(LEGACY_CODE_MAP); // { 300: 305, 301: 306 }

// Automatic translation in classifyAndValidate()
const oldMessage = { message_type: 301, /* ... */ };
const { kind, result } = classifyAndValidate(oldMessage);
// kind === 'gatewayMetrics' (automatically translated 301→306)

HTTP Transport Support (v0.8.0+):

New transport_metadata field enables HTTP REST API integration:

const httpMessage = {
  schema_version: 1,
  message_type: 101, // DEVICE_DATA
  device_id: 'SN001',
  device_type: 'sensor',
  timestamp: new Date().toISOString(),
  firmware_version: 'SN 2.1.5',
  transport_metadata: {
    protocol: 'http',
    correlation_id: 'req-12345',
    http: {
      method: 'POST',
      path: '/api/v1/telemetry',
      status_code: 200,
      request_id: 'req-uuid-12345'
    }
  },
  sensors: { temp: { value: 22.5, unit: 'C' } }
};

Provided Schemas (v1)

| File | Purpose | |------|---------| | envelope.schema.json | Base required envelope fields (now with optional message_type) | | sensor_data.schema.json | Telemetry payload with sensors map | | sensor_heartbeat.schema.json | Lightweight heartbeat (firmware_version may be omitted) | | sensor_status.schema.json | Sensor status / presence updates | | sensor_info.schema.json | Sensor identification and capabilities (v0.7.2+) | | sensor_metrics.schema.json | Sensor health and performance metrics (v0.7.2+) | | gateway_info.schema.json | Gateway identity & capabilities | | gateway_metrics.schema.json | Gateway performance metrics | | gateway_data.schema.json | Gateway telemetry readings (v0.7.2+) | | gateway_heartbeat.schema.json | Gateway presence/health check (v0.7.2+) | | gateway_status.schema.json | Gateway status change notification (v0.7.2+) | | firmware_status.schema.json | Firmware update lifecycle events (enhanced v0.7.2+) | | control_response.schema.json | Command/control response messages (deprecated, use command_response) | | command.schema.json | Device control commands (v0.5.0+) | | command_response.schema.json | Command execution responses with correlation (v0.5.0+) | | mesh_node_list.schema.json | Mesh network node list with status | | mesh_topology.schema.json | Mesh network topology and connections | | mesh_alert.schema.json | Mesh network alerts and warnings | | mesh_bridge.schema.json | Mesh protocol bridge for painlessMesh integration (v0.7.1+) | | mesh_status.schema.json | Mesh network health status (v0.7.2+) | | mesh_metrics.schema.json | Mesh network performance metrics (v0.7.2+) | | device_config.schema.json | Unified device configuration management for sensors & gateways (v0.7.1+) | | batch_envelope.schema.json | Message batching for 50-90% protocol overhead reduction (v0.7.3+) | | compressed_envelope.schema.json | Compressed message envelope for bandwidth optimization (v0.7.3+) |

Exports

| Export | Type | Description | |--------|------|-------------| | validators | object | Precompiled validators per message type | | validateMessage(kind,data) | fn | Run a specific validator by key | | classifyAndValidate(data) | fn | Fast classification + validation (uses message_type if present) | | MessageTypeCodes | const object | Message type code constants (v0.7.2+) | | SensorDataMessage etc. | TS interfaces | Strongly typed shapes | | isSensorDataMessage etc. | type guards | Runtime narrowing helpers | | SensorInfoMessage, SensorMetricsMessage | TS interfaces | New sensor types (v0.7.2+) | | GatewayDataMessage, GatewayHeartbeatMessage, GatewayStatusMessage | TS interfaces | New gateway types (v0.7.2+) | | MeshStatusMessage, MeshMetricsMessage | TS interfaces | New mesh types (v0.7.2+) | | MeshBridgeMessage | TS interface | Mesh bridge message type (v0.7.1+) | | BatchEnvelopeMessage, CompressedEnvelopeMessage | TS interfaces | New message types (v0.7.3+) | | isSensorInfoMessage, isSensorMetricsMessage etc. | type guards | Type guards for new messages (v0.7.2+) | | isBatchEnvelopeMessage, isCompressedEnvelopeMessage | type guards | Type guards for new messages (v0.7.3+) | | schemas/*.json | JSON | Original schema assets (optional) |

Validator Keys

sensorData, sensorHeartbeat, sensorStatus, sensorInfo (v0.7.2+), sensorMetrics (v0.7.2+), gatewayInfo, gatewayMetrics, gatewayData (v0.7.2+), gatewayHeartbeat (v0.7.2+), gatewayStatus (v0.7.2+), firmwareStatus, controlResponse, command, commandResponse, meshNodeList, meshTopology, meshAlert, meshBridge (v0.7.1+), meshStatus (v0.7.2+), meshMetrics (v0.7.2+), deviceConfig (v0.7.1+), batchEnvelope (v0.7.3+), compressedEnvelope (v0.7.3+)

Classification Strategy

v0.7.3+ Fast Path (when message_type present):

  • Direct O(1) lookup using message type code (200-605, 700, 800, 810)
  • Supports all 23 message types including batch_envelope, compressed_envelope, and all v0.7.2 additions
  • 90% faster than heuristic matching
  • Validates that structure matches declared type

Heuristics (when message_type absent - backward compatible):

  • event: "command"command (v0.5.0+)
  • event: "command_response"commandResponse (v0.5.0+)
  • event: "mesh_bridge"meshBridge (v0.7.1+)
  • event: "config_snapshot", "config_update", or "config_request"deviceConfig (v0.7.1+)
  • metrics + device_type: "sensor"sensorMetrics (v0.7.2+)
  • metrics + device_type: "gateway"gatewayMetrics
  • sensors + device_type: "gateway"gatewayData (v0.7.2+)
  • sensorssensorData
  • capabilities or available_sensorssensorInfo (v0.7.2+)
  • mesh_status field → meshStatus (v0.7.2+)
  • mesh_network_id + metricsmeshMetrics (v0.7.2+)
  • nodes array → meshNodeList
  • connections array → meshTopology
  • alerts array → meshAlert
  • progress_pct or OTA status keywords → firmwareStatus
  • status + device_type: sensorsensorStatus
  • uptime_s + device_type: gateway + no metricsgatewayHeartbeat (v0.7.2+)
  • status: online|offline|error + device_type: gatewaygatewayStatus (v0.7.2+)
  • status: ok|error (no other match) → controlResponse
  • device_type: gatewaygatewayInfo
  • fallback → sensorHeartbeat

Versioning Policy

Schema stability is paramount. We track two related versions:

| Concept | Meaning | |---------|---------| | schema_version (in payload) | Wire format major. Only increments for breaking changes. | | npm package version | Follows semver; patch/minor may add optional properties or tooling, major aligns with schema_version bump. |

Backward‑compatible additions: new optional properties or enums, documented in CHANGELOG. Breaking: new required fields, structural changes, or removed properties (triggers parallel v2 schema path & coordinated firmware rollout).

TypeScript / Bundler Notes

  • Works in TS >= 5, Node >= 16, Vite / Webpack / ESBuild.
  • Tree shaking: unused validators pruned when using ESM builds.
  • No side effects besides Ajv instance creation.

Roadmap

  • Optional custom Ajv injection hook
  • JSON Schema → Zod conversion example
  • Runtime metrics helper (count validation categories)

Contributing

Issues & PRs welcome. Ensure firmware repo schemas remain the authoritative source—do not manually edit generated schema_data.ts.

Development Workflow

Before opening a PR: Run the comprehensive validation suite:

npm run verify        # Schema sync + changelog + fixtures
npm run verify:all    # Additional schema compilation + OTA manifest validation  
npm test              # Enhanced fixture validation with detailed reporting

Available validation scripts:

  • npm run test - Cross-platform fixture validation (CJS/ESM) with enhanced error reporting
  • npm run test:ota - OTA manifest fixture validation
  • npm run verify:schemas - Ensure schemas are synced from source directory
  • npm run verify:release - Check changelog contains current version
  • npm run verify:all - Comprehensive schema compilation and fixture validation

Script Organization

Scripts are organized by category in package.json:

  • Build Scripts: build, build:cjs, build:esm, clean, etc.
  • Testing & Validation: test, verify:*, etc.
  • Release Management: release:prepare, wiki:generate
  • Repository Metadata: metadata:* (organization compliance)

Release Process

See PUBLISH_CHECKLIST.md for detailed release procedures. Quick summary:

  1. Update schemas in docs/mqtt_schema/
  2. Run npm run verify to ensure everything is valid
  3. Use npm run release:prepare -- patch|minor|major for version bumping
  4. Follow checklist for tagging and publishing

Security

Schemas are static. No network access. Supply-chain risk minimized by keeping dependencies minimal (Ajv + formats only).

License

MIT

Registry Mirrors

This package is published to BOTH:

  • Public npm registry: https://registry.npmjs.org (primary)
  • GitHub Packages registry: https://npm.pkg.github.com (mirror for visibility in repo Packages tab)

Installing from GitHub Packages (optional)

Create or update an .npmrc with a scoped registry override (auth token with read:packages required):

@alteriom:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}

Then install normally:

npm install @alteriom/mqtt-schema ajv ajv-formats

If you omit the override, npmjs.org is used (recommended for most consumers).

Why dual publish?

  • GitHub Packages listing provides provenance + quick visibility in the repo UI.
  • npm remains the canonical public distribution source (faster, anonymous installs allowed).

Operational Notes

| Aspect | Behavior | |--------|----------| | Build artifact | Built once, same tarball published to both registries. | | Version uniqueness | Same version must not be republished; bump if any change needed. | | Auth (GitHub) | Always required for install from GitHub Packages, even for public repos. | | Tarball parity | Do not rebuild between publishes; workflows ensure single build. | | Fallback strategy | If mirror publish fails (e.g., transient), primary npm publish still stands. | | Provenance flag | Applied for npm (GitHub ignores currently). |

Verifying a Release

npm view @alteriom/mqtt-schema version
npm view @alteriom/mqtt-schema version --registry=https://npm.pkg.github.com

Both should return the same version.

Repository Metadata Compliance

This repository integrates the @alteriom/repository-metadata-manager tooling to continuously validate and report on repository metadata health (description, topics, documentation signals, etc.) within the Alteriom organization standards.

Local Usage

Run a validation (non‑destructive):

npm run metadata:validate

Generate a detailed report:

npm run metadata:report

Configuration lives in metadata-config.json (organizationTag alteriom). Default detection is auto; adjust if repository classification needs overriding.

CI Workflow

Workflow file: .github/workflows/metadata-compliance.yml

On each push / PR against main it will:

  1. Install dependencies
  2. Run metadata:validate (fails job on hard non‑compliance)
  3. Always attempt a best‑effort report (metadata:report) for visibility

Tokens / Permissions

The workflow relies only on the default GITHUB_TOKEN for read operations. If future auto‑apply operations are desired, a token with elevated repo scope would be needed and the metadata:apply script could be wired (currently omitted to keep CI read‑only).

Extending

If you add new categories of tooling or documentation, re‑run the report to see updated recommendations. For cross‑repo analytics or policy generation, use the original project directly.

Applying Metadata (Manual Workflow)

For authorized maintainers you can run adjustments via GitHub Actions:

  1. Open the "Repository Metadata Apply" workflow under the Actions tab.
  2. Choose whether to keep dryRun (default) or set to false to apply.
  3. Run the workflow; the log will show proposed or applied changes.

Local dry‑run vs apply:

npm run metadata:apply:dry  # show what would change
npm run metadata:apply      # apply changes (requires proper permissions via GITHUB_TOKEN)

Note: Applying metadata modifies repository settings (description, topics) through the GitHub API; ensure the default token has the necessary repo scopes (in public repositories the workflow GITHUB_TOKEN normally suffices for these fields).

Additional Documentation

This repository maintains comprehensive documentation across several locations:

Root Documentation

docs/ Directory Structure

See docs/README.md for the complete documentation structure.