CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-arduino-iot-js

JavaScript/TypeScript library for connecting to the Arduino IoT Cloud MQTT broker with support for both browser and Node.js applications.

Overview
Eval results
Files

senml-processing.mddocs/

SenML Processing

SenML (Sensor Markup Language) utilities for IoT data encoding and processing. Handles CBOR encoding/decoding and data transformation for Arduino IoT Cloud communication.

Capabilities

CBOR Encoding/Decoding

Core CBOR functionality for SenML message processing. CBOR is directly exported from the Arduino CBOR package.

/** CBOR encoder/decoder from @arduino/cbor-js package */
const CBOR: {
  /** Encode SenML array to CBOR binary format */
  encode(value: SenML[], numericKeys?: boolean): ArrayBuffer;
  /** Decode CBOR binary data to SenML array with optional tagger and simpleValue */
  decode(data: ArrayBuffer, tagger?: (value: SenML) => SenML, simpleValue?: SenML): SenML[];
};

Usage Examples:

import { SenML } from "arduino-iot-js";

// Encode SenML to CBOR
const senmlData: SenML.SenML[] = [{
  n: "temperature",
  v: 25.5,
  t: Date.now()
}];

const cborBuffer = SenML.CBOR.encode(senmlData);
console.log("CBOR encoded:", cborBuffer);

// Decode CBOR back to SenML
const decodedData = SenML.CBOR.decode(cborBuffer);
console.log("Decoded SenML:", decodedData);

// Use numeric keys for compact encoding
const compactBuffer = SenML.CBOR.encode(senmlData, true);

SenML Data Parsing

Convert property values to SenML format for transmission.

/**
 * Parse property value to SenML format
 * @param name - Property name
 * @param value - Property value (string, number, boolean, or object)
 * @param timestamp - Timestamp for the value
 * @param useCloudProtocolV2 - Use cloud protocol v2 format
 * @param deviceId - Device identifier
 * @returns SenML record or array of records
 * @throws Error if timestamp is not integer or name is invalid
 */
function parse(
  name: string,
  value: CloudMessageValue,
  timestamp: number,
  useCloudProtocolV2: boolean,
  deviceId: string
): SenML | SenML[];

Usage Examples:

import { SenML, type CloudMessageValue } from "arduino-iot-js";

// Parse simple values
const tempSenML = SenML.parse("temperature", 25.5, Date.now(), true, "device-123");
console.log("Temperature SenML:", tempSenML);

const statusSenML = SenML.parse("status", "active", Date.now(), true, "device-123");
console.log("Status SenML:", statusSenML);

const enabledSenML = SenML.parse("enabled", true, Date.now(), true, "device-123");
console.log("Enabled SenML:", enabledSenML);

// Parse object values (creates multiple SenML records)
const sensorData = {
  temperature: 25.5,
  humidity: 60,
  pressure: 1013.25
};

const objectSenML = SenML.parse("sensors", sensorData, Date.now(), true, "device-123");
console.log("Object SenML:", objectSenML);
// Results in multiple SenML records: sensors:temperature, sensors:humidity, sensors:pressure

SenML Data Formatting

Format individual values as SenML records.

/**
 * Format a single value as SenML record
 * @param value - The value to format
 * @param name - Property name
 * @param timestamp - Timestamp (-1 to omit)
 * @param deviceId - Device identifier
 * @returns SenML record
 */
function format(
  value: CloudMessageValue,
  name: string,
  timestamp: number,
  deviceId: string
): SenML;

Usage Examples:

import { SenML } from "arduino-iot-js";

// Format individual values
const tempRecord = SenML.format(25.5, "temperature", Date.now(), "device-123");
const humidityRecord = SenML.format(60, "humidity", -1, null); // No timestamp, no device ID

console.log("Temperature record:", tempRecord);
// Output: { bt: 1694123456789, n: "temperature", v: 25.5, bn: "urn:uuid:device-123" }

console.log("Humidity record:", humidityRecord);
// Output: { n: "humidity", v: 60 }

SenML String Encoding

Convert SenML arrays to base64 encoded strings.

/**
 * Convert SenML array to base64 encoded CBOR string
 * @param value - SenML array to encode
 * @param numericKeys - Use numeric keys for compact encoding
 * @returns Base64 encoded string
 */
function toString(value: SenML[], numericKeys?: boolean): string;

Usage Examples:

import { SenML } from "arduino-iot-js";

const senmlData: SenML[] = [
  { n: "temperature", v: 25.5, t: Date.now() },
  { n: "humidity", v: 60, t: Date.now() }
];

// Convert to base64 string
const base64String = SenML.toString(senmlData);
console.log("Base64 encoded:", base64String);

// Use numeric keys for more compact encoding
const compactString = SenML.toString(senmlData, true);
console.log("Compact base64:", compactString);

Cloud Protocol V2 Conversion

Convert SenML to Cloud Protocol V2 format.

/**
 * Convert SenML record to Cloud Protocol V2 format (numeric keys)
 * @param cborValue - SenML record to convert
 * @returns SenML record with numeric keys
 */
function toCloudProtocolV2(cborValue: SenML): SenML;

Usage Examples:

import { SenML } from "arduino-iot-js";

const originalSenML: SenML = {
  bn: "urn:uuid:device-123",
  n: "temperature",
  v: 25.5,
  t: Date.now()
};

const v2SenML = SenML.toCloudProtocolV2(originalSenML);
console.log("V2 format:", v2SenML);
// Output uses numeric keys: { -2: "urn:uuid:device-123", 0: "temperature", 2: 25.5, 6: 1694123456789 }

Value and Name Extraction

Extract values and names from SenML records or string arrays.

/**
 * Extract value from SenML record or string array
 * @param message - SenML record or string array
 * @returns The value (from v, vs, or vb fields)
 */
function valueFrom(message: SenML | string[]): CloudMessageValue;

/**
 * Extract name from SenML record or string array
 * @param property - SenML record or string array
 * @returns The property name
 */
function nameFrom(property: SenML | string[]): string;

/**
 * Type guard to check if message is SenML record
 * @param message - Message to check
 * @returns True if message is SenML record
 */
function isPropertyValue(message: SenML | string[]): message is SenML;

/**
 * Check if value is null or undefined
 * @param v - Value to check
 * @returns True if value is null or undefined
 */
function isNil<T>(v: T): boolean;

/**
 * Take the first non-nil value from provided values
 * @param values - Values to check
 * @returns First non-nil value
 */
function takeFrom(...values: CloudMessageValue[]): CloudMessageValue;

Usage Examples:

import { SenML } from "arduino-iot-js";

// Extract from SenML record
const senmlRecord: SenML = { n: "temperature", v: 25.5 };
const value = SenML.valueFrom(senmlRecord);
const name = SenML.nameFrom(senmlRecord);

console.log(`${name}: ${value}`); // "temperature: 25.5"

// Extract from string array format
const stringArray = ["temperature", "unit", 25.5];
const arrayValue = SenML.valueFrom(stringArray);
const arrayName = SenML.nameFrom(stringArray);

console.log(`${arrayName}: ${arrayValue}`); // "temperature: 25.5"

// Type checking
if (SenML.isPropertyValue(senmlRecord)) {
  console.log("This is a SenML record");
  console.log("Name field:", senmlRecord.n);
}

Utility Functions

Helper functions for SenML processing.

/**
 * Check if value is null or undefined
 * @param v - Value to check
 * @returns True if value is nil
 */
function isNil<T>(v: T): boolean;

/**
 * Return first non-nil value from arguments
 * @param values - Values to check
 * @returns First non-nil value
 */
function takeFrom(...values: CloudMessageValue[]): CloudMessageValue;

Usage Examples:

import { SenML } from "arduino-iot-js";

// Check for nil values
const temperature = undefined;
if (SenML.isNil(temperature)) {
  console.log("Temperature value is missing");
}

// Take first valid value
const sensorValue = SenML.takeFrom(undefined, null, 25.5, 30.0);
console.log("Sensor value:", sensorValue); // 25.5

SenML Type Definitions

interface SenML {
  /** Base name for this record */
  bn?: string;
  /** Base time for this record */
  bt?: number;
  /** Base unit for this record */
  bu?: string;
  /** Base value for this record */
  bv?: number;
  /** Base sum for this record */
  bs?: number;
  /** Base version for this record */
  bver?: number;
  /** Name of this sensor */
  n?: string;
  /** Unit of this sensor reading */
  u?: string;
  /** Numeric value */
  v?: number;
  /** String value */
  vs?: string;
  /** Boolean value */
  vb?: boolean;
  /** Data value (blob) */
  vd?: string;
  /** Sum value */
  s?: number;
  /** Time when this reading was taken */
  t?: number;
  /** Update time for this reading */
  ut?: number;
  /** Allow additional properties */
  [key: string]: any;
}

Advanced Usage

Custom SenML Processing

import { SenML, type CloudMessageValue } from "arduino-iot-js";

// Process complex sensor data
function processSensorReading(
  deviceId: string,
  readings: Record<string, any>
): string {
  const timestamp = Date.now();
  const senmlRecords: SenML[] = [];

  Object.entries(readings).forEach(([sensor, value]) => {
    const senmlRecord = SenML.format(value, sensor, timestamp, deviceId);
    const v2Record = SenML.toCloudProtocolV2(senmlRecord);
    senmlRecords.push(v2Record);
  });

  return SenML.toString(senmlRecords, true);
}

// Usage
const sensorData = {
  temperature: 25.5,
  humidity: 60,
  pressure: 1013.25,
  light: 850
};

const encodedData = processSensorReading("device-123", sensorData);
console.log("Encoded sensor data:", encodedData);

Message Parsing Pipeline

import { SenML } from "arduino-iot-js";

// Parse incoming CBOR messages
function parseIncomingMessage(buffer: ArrayBuffer): Array<{name: string, value: any}> {
  try {
    const senmlArray = SenML.CBOR.decode(buffer);

    return senmlArray.map(record => ({
      name: SenML.nameFrom(record),
      value: SenML.valueFrom(record)
    }));
  } catch (error) {
    console.error("Failed to parse CBOR message:", error);
    return [];
  }
}

// Create outgoing messages
function createMessage(
  propertyName: string,
  value: CloudMessageValue,
  deviceId: string
): ArrayBuffer {
  const senmlData = SenML.parse(propertyName, value, Date.now(), true, deviceId);
  const senmlArray = Array.isArray(senmlData) ? senmlData : [senmlData];

  return SenML.CBOR.encode(senmlArray, true);
}

Install with Tessl CLI

npx tessl i tessl/npm-arduino-iot-js

docs

connection-management.md

index.md

property-operations.md

senml-processing.md

tile.json