Understanding Devices

Devices are the starting point of every Vesbite automation. They are the physical IoT hardware – RFID readers, barcode scanners, sensors, printers – that generate data and accept commands. This document explains how Vesbite models devices, why the adoption process exists, and how the different device capabilities work together.

Schema-Driven Design

Every device in Vesbite is defined by a device type, and every device type carries a schema. The schema is a structured definition of everything the device can do:

  • Events it can publish (e.g., a tag scan, a sensor reading)
  • Actions it can accept (e.g., start scanning, print a label)
  • Settings that control its behavior (e.g., power level, polling interval)
  • Statuses it can report (e.g., Idle, Reading, Error)

This design has an important consequence: Vesbite does not need to know about specific hardware in advance. When a new device type is introduced, it brings its own schema. The platform reads that schema and automatically generates the appropriate UI, exposes the right triggers and actions in the Flow builder, and validates settings against the defined constraints.

{
  "deviceType": "rfid-reader",
  "events": {
    "tagRead": {
      "fields": ["epc", "tid", "rssi", "antenna", "timestamp"]
    }
  },
  "actions": {
    "startInventory": {
      "parameters": ["mode", "power"],
      "returns": ["success"]
    },
    "stopInventory": {
      "parameters": [],
      "returns": ["success"]
    }
  },
  "settings": {
    "transmitPower": {
      "type": "number",
      "min": 10,
      "max": 30,
      "default": 25
    },
    "session": {
      "type": "string",
      "enum": ["S0", "S1", "S2", "S3"],
      "default": "S1"
    }
  },
  "statuses": ["Idle", "Scanning", "Error"]
}

Because the schema drives the UI, you never need to memorize what a device can do. The platform shows you.

The Adoption Process

Before a device can be managed through Vesbite, it must be adopted into a tenant. Adoption is a deliberate, user-initiated process – and that is by design.

Why adoption exists

Adoption solves two problems:

  1. Security. Devices connect over a network, and Vesbite needs to ensure that only authorized devices join your workspace. The adoption code acts as a shared secret: the device generates it, and a human enters it in the dashboard. This confirms that the person adding the device has physical access to it.

  2. Zero-configuration. Devices do not need to be pre-configured with tenant IDs, API keys, or server addresses. They only need to generate an adoption code and wait. The platform handles the rest – establishing the secure connection, synchronizing the schema, and registering the device in the correct tenant.

How adoption works

  1. The device starts up and generates a short, unique adoption code
  2. A user enters that code in the Vesbite dashboard
  3. Vesbite establishes a secure, persistent connection to the device
  4. The device’s schema is synchronized – events, actions, settings, and statuses are all registered
  5. The device appears in the tenant’s device registry, ready to use

Once adopted, the device is permanently associated with that tenant. It can be renamed, configured, and used in Flows immediately.

Device Lifecycle

A device moves through a clear lifecycle:

Registration → Adoption → Active (Online/Offline) → [Removed]

Registration. The device starts its agent and registers itself with the Vesbite platform, generating an adoption code. At this point, the device is known to the system but not associated with any tenant.

Adoption. A user claims the device by entering its code. The device is now linked to a specific tenant and its schema is fully synchronized.

Active. The device is part of the tenant and operates normally. Its connection status is tracked as either Online or Offline based on heartbeat signals (more on this below).

Removed. A user can remove a device from their tenant. This severs the connection and clears the device from the registry.

Events

Events are data that a device publishes to the platform. They represent things that happen in the physical world: a tag was scanned, a temperature was measured, a button was pressed.

Each event has a type (sometimes called a topic) and a payload. The type identifies what kind of event it is. The payload carries the data.

For example, an RFID reader might publish a tagRead event with this payload:

{
  "epc": "E2801160600002095012E177",
  "rssi": -45,
  "antenna": 1,
  "timestamp": "2026-03-20T14:30:00Z"
}

Events flow from the device to the platform over a real-time message bus. They can:

  • Trigger a Flow – a Device Event trigger starts a new workflow instance every time a matching event arrives
  • Be awaited mid-Flow – an Await Device Event action suspends a running workflow until the expected event arrives
  • Be viewed in the device logs – every event is recorded for debugging and auditing

Devices publish events regardless of whether any Flow is listening. This means you can adopt a device and observe its behavior before building any automation.

Actions

Actions are commands sent from the platform to the device. They represent things you want the device to do: start scanning, print a label, reboot, change mode.

Actions follow a request/reply pattern. The platform sends the command, and the device responds with a result. This is important because it means actions are not fire-and-forget – your Flow knows whether the action succeeded and can branch accordingly.

Platform                          Device
   │                                │
   │──── startInventory(mode) ─────>│
   │                                │
   │<──── { success: true } ────────│

In a Flow, you can use a Device Action node to send a command and then reference the result in subsequent nodes using expressions:

{{ output("start-reader").success }}

Actions are defined in the device schema, so the Flow builder knows exactly what parameters each action requires and what it returns.

Settings

Settings are configuration values that control how a device behaves. Unlike actions (which are one-time commands), settings are persistent – they remain in effect until changed.

Examples:

  • RFID reader transmit power (10-30 dBm)
  • Sensor polling interval (every 5 seconds, every minute)
  • Printer label dimensions and format

Settings are schema-driven, which means the device type defines what settings exist, their data types, allowed values, and defaults. Vesbite uses this schema to automatically generate a settings form in the UI – no custom frontend code needed.

When you change a setting, Vesbite pushes the new value to the device. The device applies it and confirms. Settings can be changed through:

  • The device settings UI in the dashboard
  • A workflow action (Set Device Settings node)
  • The API

Settings are populated with schema defaults when a device is first adopted, so devices work out of the box with sensible configuration.

Statuses

Statuses represent the device’s current operational state as reported by the device itself. They are distinct from the connection status (Online/Offline) because they describe what the device is doing, not whether it is reachable.

Common statuses include:

  • Idle – powered on, connected, waiting for commands
  • Scanning – actively reading tags or scanning barcodes
  • Processing – executing an internal operation
  • Error – the device has encountered a problem

Statuses are defined in the device schema, so each device type can have its own set of meaningful states. The current status is visible on the device detail page and can be used as a condition in Flow expressions.

Heartbeat and Connection Monitoring

Vesbite tracks whether each device is Online or Offline using a heartbeat mechanism.

The device agent sends periodic heartbeat signals to the platform. If heartbeats stop arriving, Vesbite marks the device as Offline after a timeout period. When heartbeats resume, the device returns to Online status.

This is tracked via the LastHeartbeatAt timestamp on each device. The connection status is separate from the device’s operational status – a device can be Online but in an Error state, or Offline because it was powered down while Idle.

Heartbeat monitoring lets you:

  • See at a glance which devices are connected
  • Build Flows that react to devices going offline
  • Diagnose connectivity issues without physical access to the device

Device Independence

A key design principle in Vesbite: devices work independently of Flows.

This means:

  • You can send actions to a device directly from the device page, without any Flow
  • You can change settings at any time, regardless of workflow state
  • Devices publish events whether or not a Flow is subscribed
  • The Vesbite API gives you programmatic access to all device operations

This independence is deliberate. It lets you:

  • Debug devices in isolation – verify that a reader is scanning correctly before building automation around it
  • Build Flows incrementally – adopt a device, observe its events, then add automation when you are ready
  • Use Vesbite as a backend – if you are building your own application, you can use the API to control devices without using the Flow builder at all

Devices are first-class citizens, not just inputs to workflows.

Next Steps