Your First Device

Your First Device

Learn how to build your first device entrypoint with DeviceSDK

What is a Device Entrypoint?

A device entrypoint is a TypeScript class that handles communication between your devices and your cloud code.

Basic Structure

Every device entrypoint extends the DeviceEntrypoint class:

import { DeviceEntrypoint, type DeviceResponse } from '@devicesdk/core';

export default class MyDevice extends DeviceEntrypoint {
  async onDeviceConnect() {
    // Called when a device connects
    console.log(`Device connected`);
  }

  async onMessage(message: DeviceResponse) {
    // Called when a device sends a message
    console.log(`Received from`, message);
  }

  async onDeviceDisconnect() {
    // Called when a device disconnects
    console.log(`Device disconnected`);
  }
}

Handling Device Connections

The onDeviceConnect method is called whenever a device establishes a WebSocket connection:

async onDeviceConnect() {
  // Initialize device state
  await this.env.DEVICE.kv.put('status', 'online');
}

Receiving Messages from Devices

Handle incoming messages in the onMessage method:

async onMessage(message: DeviceResponse) {
  switch (message.type) {
    case 'pin_state_update':
      // Store sensor data
      console.info(`Pin ${message.payload.pin}: ${message.payload.value}`);
      break;

    case 'gpio_state_changed':
      // Respond to button press
      await this.env.DEVICE.setGpioState(99, "high");
      break;
  }
}

Sending Commands to Devices

Send commands to your devices using the typed methods:

// Turn on an LED
await this.env.DEVICE.setGpioState(25, "high");

// Read a pin state
const reading = await this.env.DEVICE.getPinState(26, "analog");

Complete Example: LED Controller

Here’s a complete example that controls an LED based on button presses:

import { DeviceEntrypoint, type DeviceResponse } from '@devicesdk/core';

export default class LEDController extends DeviceEntrypoint {
  async onDeviceConnect() {
    // Configure button input on GPIO 20
    await this.env.DEVICE.configureGpioInputMonitoring(20, true, "up");

    console.info(`Device initialized`);
  }

  async onMessage(message: DeviceResponse) {
    if (message.type === 'gpio_state_changed' && message.payload.pin === 20) {
      // Button pressed (pulled low)
      if (message.payload.state === 'low') {
        // Toggle LED
        await this.env.DEVICE.setGpioState(25, "high");
        console.info('LED ON');
      } else {
        await this.env.DEVICE.setGpioState(25, "low");
        console.info('LED OFF');
      }
    }
  }

  async onDeviceDisconnect() {
    console.info(`Device disconnected`);
  }
}

Testing in the Simulator

Use the local simulator to test your device code:

npx @devicesdk/cli dev

The simulator provides:

  • Virtual GPIO pins you can toggle
  • Simulated button presses
  • Mock sensor readings
  • Real-time message visualization

Deploying to Real Hardware

Once tested, deploy your code:

npx @devicesdk/cli deploy

Then flash the firmware to your device:

npx @devicesdk/cli flash

Environment Bindings

Your device entrypoint has access to several environment bindings:

  • console.log / console.info / etc. - Logging (automatically captured and persisted)
  • this.env.DEVICE - Send messages to device
  • this.env.DEVICE.kv - Key-value storage for device state

Next Steps

Need Help?