Skip to main content
Version: 1.0

SheLr

caution

SheLr is currently offered as a preview API. While it is fully functional and ready for evaluation and integration work, some aspects of the API — such as method names, parameters, semantics and on-the-wire details — may still be refined in upcoming firmware releases as we incorporate feedback. We recommend keeping this in mind when planning production deployments.

SheLr components are a subset of dynamic components that implement Shelly Long-Range Protocol (SheLR) — a secure transport layered on top of the LoRa Add-on radio. Each SheLr instance owns its own logical address, AES-CCM key slots, payload-accept mask, and per-peer replay-protection state.

A SheLr instance requires an enabled and operational LoRa Add-on. The LoRa add-on is the transport (one radio per device); multiple SheLr instances can coexist on top of it, each terminating its own address space, key set, and traffic class.

info
  • Up to 5 SheLr instances can coexist on a single device (SHELLY_SHELR_MAX_COMPONENTS = 5).
  • Dynamic component ids for SheLr instances are in the closed range [200, 299].

The management is accomplished through RPC methods within the SheLr namespace:

Methods​

SheLr.Create​

Creates a new SheLr component instance bound to the local LoRa radio. SheLr instances are dynamic components — they are persisted across reboots and can be deleted at runtime via SheLr.Delete.

Parameters:

PropertyTypeDescription

config

object

SheLr configuration for the new instance. See Configuration. Required

id

number

Optional desired component id in the closed range [200, 299]. If omitted, the next free id in that range is assigned

Response:

PropertyTypeDescription

id

number

The id assigned to the newly created SheLr instance

info
  • Up to 5 SheLr instances may coexist on a device. SheLr.Create returns a resource-exhausted error once the limit is reached.
  • Dynamic component ids must fall in [200, 299]. Passing an id outside this range returns an "Invalid argument" error.

Example: SheLr.Create Example​

SheLr.Delete​

Deletes an existing SheLr component instance. The instance's persisted configuration and replay-protection state are erased; a subsequently re-created instance with the same id starts from a clean state.

Parameters:

PropertyTypeDescription

id

number

Id of the SheLr instance to delete

Response:

null on success; error if the request can not be executed or failed.

Example: SheLr.Delete Example​

SheLr.GetConfig​

Retrieves the configuration of a SheLr instance.

Parameters:

PropertyTypeDescription

id

number

Id of the SheLr instance

Find more about the config properties in Configuration.

Example: SheLr.GetConfig Example​

SheLr.SetConfig​

Updates the configuration of a SheLr instance.

Parameters:

PropertyTypeDescription

id

number

Id of the SheLr instance

config

object

SheLr configuration object. See Configuration

Response:

PropertyTypeDescription

restart_required

boolean

true if the device must be restarted for the new configuration to take effect, false otherwise

Example: SheLr.SetConfig Example​

SheLr.GetStatus​

Retrieves the status of a SheLr instance.

Parameters:

PropertyTypeDescription

id

number

Id of the SheLr instance

Find more about the status properties in Status.

Example: SheLr.GetStatus Example​

SheLr.Send​

Sends a user payload over LoRa RF using SheLR. For more details see info below.

Parameters:

PropertyTypeDescription

id

number

Id of the SheLr instance

lr_addr

string

The address of the recipient in the LoRa network as a hexadecimal string. Unicast, multicast and broadcast destinations are supported. See Addressing

data

string

Data to be sent (remark: data should be encoded in 'base64')

tx_key

string

Inline base64-encoded 128-bit AES key to encrypt this single send with. optional. Mutually exclusive with tx_key_id. See Encryption

tx_key_id

number

Configured TX key slot to use for this single send. Possible values: [1, 3]. optional. Mutually exclusive with tx_key. See Encryption

Response:

null on success; error if the request can not be executed or failed

info

LoRa RF using SheLR:

  • SheLR gives more benefits than raw LoRa: AES-CCM authenticated encryption, unicast, multicast and broadcast addressing, and replay protection
  • Using LoRa RF over SheLR should be considered preferable to LoRa.SendBytes
  • For details on lr_addr formatting and addressing modes see Addressing; for key handling see Encryption
  • Requires "user" to be present in the SheLr instance's accept configuration on both sender and receiver

Example: SheLr.Send Example​

SheLr.Call​

Invokes an RPC method on a remote device over LoRa RF using SheLR. The call is unicast — lr_addr must be a specific device address, not a multicast or broadcast address.

Parameters:

PropertyTypeDescription

id

number

Id of the SheLr instance

lr_addr

string

The address of the recipient in the LoRa network as a hexadecimal string. Must be unicast — multicast and broadcast destinations are rejected. See Addressing

method

string

The RPC method name to invoke on the remote device. Required, non-empty

params

object

Parameters to pass to the remote method, optional

tx_key

string

Inline base64-encoded 128-bit AES key to encrypt this single call with. optional. Mutually exclusive with tx_key_id. See Encryption

tx_key_id

number

Configured TX key slot to use for this single call. Possible values: [1, 3]. optional. Mutually exclusive with tx_key. See Encryption

Response:

The response object returned by the remote device for the invoked RPC method (the contents of the JSON-RPC result). On failure (remote JSON-RPC error, send failure, or timeout) an error is returned to the caller.

info

SheLr.Call over SheLR:

  • SheLr.Call works only with SheLR-capable devices and requires encryption keys to be configured on both sides
  • Both the local SheLr instance's and the remote SheLr instance's accept configuration must include the "rpc" payload type
  • SheLr.Call is strictly unicast — lr_addr must address a single peer. Multicast (*FFFF) or broadcast (FFFFFFFF) destinations are rejected locally with an Invalid argument error before any frame is transmitted. To send an RPC to a group, use SheLr.Notify instead
  • SheLr.Call waits for a response from the remote device. If no response is received within the default timeout (30 seconds), the call fails with an error
  • Up to 20 outbound calls may be in flight at the same time per SheLr instance

Example: SheLr.Call Example​

SheLr.Notify​

Sends a JSON-RPC notification to a remote device (or group / broadcast) over LoRa RF using SheLR. Unlike SheLr.Call, no response is expected from the remote device.

Parameters:

PropertyTypeDescription

id

number

Id of the SheLr instance

lr_addr

string

The address of the recipient in the LoRa network as a hexadecimal string. Unicast, multicast (e.g. "0001FFFF") and broadcast ("FFFFFFFF") destinations are supported. See Addressing

method

string

The RPC method name to invoke as a notification on the remote device(s). Required, non-empty

params

object

Parameters to pass to the remote method, optional

tx_key

string

Inline base64-encoded 128-bit AES key to encrypt this single notification with. optional. Mutually exclusive with tx_key_id. See Encryption

tx_key_id

number

Configured TX key slot to use for this single notification. Possible values: [1, 3]. optional. Mutually exclusive with tx_key. See Encryption

Response:

null on successful local send; error if the request can not be executed or the local send failed. There is no acknowledgement from the remote device.

info

SheLr.Notify over SheLR:

  • SheLr.Notify is a fire-and-forget notification — it does not wait for a response from the remote device
  • Both the local SheLr instance's and the remote SheLr instance's accept configuration must include the "rpc" payload type
  • Multicast (e.g. "0001FFFF") and broadcast ("FFFFFFFF") destinations are supported

Example: SheLr.Notify Example​

SheLr.ResetRxCounter​

Clears the local SheLR replay-protection state for a single remote peer. Use this when the remote peer has been factory-reset, re-paired, or its message counter has otherwise rolled back, causing legitimate frames to be rejected as replays.

Parameters:

PropertyTypeDescription

id

number

Id of the SheLr instance

lr_addr

string

The address of the remote peer whose RX replay state should be cleared, as a hexadecimal string. Must be unicast (not multicast or broadcast)

Response:

null on success; error if the request can not be executed or failed.

info

SheLr.ResetRxCounter over SheLR:

  • The reset is local-only — it does not transmit anything over LoRa RF
  • Only the replay state for the specified lr_addr is cleared; state for other peers is preserved
  • After reset, the next authenticated frame from the peer will be accepted regardless of its msg_id, and replay tracking will resume from that point
  • Typical use cases: first-time pairing, recovery after peer reset, or recovery after a peer's message counter has rolled

Example: SheLr.ResetRxCounter Example​

SheLR Protocol​

Shelly Long-Range Protocol (SheLR) is the secure protocol that sits on top of the raw LoRa link. It is used by SheLr.Send, SheLr.Call, SheLr.Notify and SheLr.ResetRxCounter.

It is organized into one shared transport, used by every SheLR frame, and two application-level channels carried on top of it:

  • Transport envelope — common to every SheLR frame regardless of what it carries. Handles addressing, authenticated encryption / key management, and replay protection.
  • User messaging — opaque application payloads sent by SheLr.Send and delivered to the receiver's host / script as a user_rx event.
  • RPC channel — JSON-RPC requests and notifications sent by SheLr.Call and SheLr.Notify and dispatched against the receiver's local RPC surface.

This section documents the public protocol semantics needed to interoperate with SheLR-capable Shelly devices.

Transport envelope​

The transport envelope is shared by all SheLR traffic. It defines how peers are addressed, how frames are encrypted and authenticated, and how replays are detected. These rules apply equally to user and rpc payloads.

Addressing​

A SheLR address (lr_addr) is a 32-bit value, represented in API parameters as an 8-character hexadecimal string. The upper 16 bits encode the group and the lower 16 bits encode the device within the group:

  upper 16 bits        lower 16 bits
+-----------------+-----------------+
| group | device |
+-----------------+-----------------+
FormRuleExampleMeaning
Unicastgroup ≠ FFFF and device ≠ FFFF00010042Single peer in group 0x0001
Multicastgroup ≠ FFFF and device == FFFF0001FFFFAll devices in group 0x0001
Broadcastlr_addr == FFFFFFFFFFFFFFFFAll SheLR devices on the network

Per-method address constraints:

MethodUnicastMulticastBroadcast
SheLr.Sendyesyesyes
SheLr.Callyesnono
SheLr.Notifyyesyesyes
SheLr.ResetRxCounteryesnono

A receiver accepts a frame if and only if:

  • the destination is broadcast (FFFFFFFF), or
  • the destination is multicast and the receiver's own group matches, or
  • the destination is unicast and equal to the receiver's own addr (group and device).

Encryption​

SheLR uses AES-128-CCM authenticated encryption. Each SheLr instance stores up to three key slots (key1, key2, key3), each holding a base64-encoded 128-bit (16-byte) AES key.

  • TX uses the SheLr instance's configured TX key slot (tx_key_id), unless overridden per-call via tx_key (inline base64 key) or tx_key_id (slot index). If neither is provided per-call, the configured slot is used; if the selected slot is empty, an error is returned.
  • tx_key and tx_key_id are mutually exclusive within a single RPC call.
  • RX tries all non-empty key slots in order and accepts the first that successfully decrypts and authenticates the frame.
  • When replying to an inbound SheLR RPC request, the device encrypts the response with the same key that decrypted the request. This allows safe key rotation: as long as the new key is added to a free slot before the old one is removed, in-flight RPC responses are not lost.

Keys can be generated with, for example:

openssl rand -base64 16

Replay protection​

Every SheLR frame carries a monotonically increasing 32-bit msg_id issued by the sender. Each receiver tracks, per-sender, the highest accepted msg_id (plus a small window for out-of-order tolerance) and rejects any authenticated frame whose msg_id is not greater than the tracked maximum.

  • Replay state is persisted across reboots.
  • Replay checks run after authenticated decryption, so unauthenticated traffic cannot poison the tracker.
  • If a peer is factory-reset, re-paired, or its message counter is otherwise rolled back, its frames will be rejected as replays until the local replay state for that peer is cleared with SheLr.ResetRxCounter.

User messaging​

Once a frame has been authenticated, decrypted, and accepted by the transport envelope (address match, replay check OK), its payload is dispatched according to its payload type. SheLR defines two payload types — user and rpc — gated by the receiving SheLr instance's accept configuration on both sides:

TypeSent byTerminates at (on RX)
userSheLr.Senduser_rx event — delivered to the host/script
rpcSheLr.Call, SheLr.NotifyLocal RPC dispatcher — invokes the named method on the device

Frames whose payload type is not listed in the receiver's accept configuration are silently dropped after successful decryption. The same check is applied on TX: SheLr.Send requires user, while SheLr.Call and SheLr.Notify require rpc.

The user payload is an opaque binary message — SheLR does not inspect or parse its contents.

  • Sent by: SheLr.Send.
  • Carried as: the base64-encoded data argument of SheLr.Send, transmitted verbatim after AES-CCM encryption.
  • Terminated at: the receiving device emits a user_rx notification event carrying data, the sender address, rssi, snr and tsu. The payload is not interpreted by the firmware; it is delivered to the host application / script for processing.
  • Use it for: custom application protocols, telemetry, sensor readings, or any opaque byte stream you want to ship between two SheLR peers.

RPC channel​

JSON-RPC 2.0 frame carried inside SheLR.

  • Sent by: SheLr.Call (request, response expected) and SheLr.Notify (notification, no response).
  • Carried as: a JSON-RPC frame:
    • Request (SheLr.Call): method, optional params, and an id allocated by the sender.
    • Notification (SheLr.Notify): method and optional params, no id.
    • Response: the request's id and exactly one of result or error.
  • Terminated at: the receiver's local RPC dispatcher — the same dispatcher that handles regular JSON-RPC over HTTP / WebSocket / MQTT. The named method is executed against the device's own RPC surface and, for unicast requests, the result is returned to the caller over SheLR using the key with which the request was decrypted.
  • Use it for: remotely controlling or querying SheLR-capable Shelly devices using the same RPC methods you would call locally (e.g. Switch.Set, Switch.Toggle, Shelly.GetStatus).

Notes on rpc channel semantics:

  • SheLr.Call reserves an outbound request id automatically; clients only supply method and params.
  • The jsonrpc: "2.0" field is optional on the wire and is typically omitted to save airtime. It is ignored by receivers.
  • id must be a JSON number or string. id: null is not accepted as a request.
  • SheLr.Call is always unicast: the local handler rejects multicast and broadcast destinations with an Invalid argument error before transmitting. Only unicast peers can deliver a response.
  • A malformed unicast request may receive a JSON-RPC error response with id: null and a standard JSON-RPC error code (e.g. -32600 for Invalid Request).
  • SheLr.Call waits up to 30 seconds by default for a response; on timeout the call fails with an error. Up to 20 outbound calls may be in flight at the same time per SheLr instance.

Configuration​

A SheLr instance holds its own address, key slots, accept mask, and optional name. Configuration is exchanged as JSON via SheLr.GetConfig and SheLr.SetConfig, and the same object is passed to SheLr.Create under the config key.

Parameters:

PropertyTypeDescription

id

number

Id of the SheLr instance (read-only on SetConfig)

name

string or null

Free-form instance name. Optional

addr

string or null

Device LoRa address as an 8-character hexadecimal string. See info below

tx_key_id

number

The encryption key index, possible values: [1, 3]. optional, the default is 1

key1

string or null

The cryptography key #1 (base64-encoded 128-bit AES key). optional. Write-only on SetConfig; on GetConfig only a boolean is returned indicating whether the slot is set

key2

string or null

The cryptography key #2. Same handling as key1

key3

string or null

The cryptography key #3. Same handling as key1

accept

array of strings or empty array or null

The list of supported SheLR payload types this instance will accept on RX and is allowed to send on TX:

ValueDescription

user

user payload type — opaque binary payloads sent via SheLr.Send and received via the user_rx event

rpc

rpc payload type — JSON-RPC frames sent via SheLr.Call / SheLr.Notify and dispatched as remote RPCs on the receiver

info

SheLr settings:

The cryptography keys:

  • The cryptography keys should be encoded in 'base64'
  • The size of the keys should be 16 bytes (128 bit key)
  • To generate keys and encode them to base64 the following command could be used:

openssl rand -base64 16 (it works on Linux, macOS and Windows)

  • If tx_key_id is not provided during configuration, the default slot 1 is used; if that slot holds no key, a per-call tx_key or tx_key_id must be supplied when calling SheLr.Send, SheLr.Call or SheLr.Notify, otherwise an error is returned
  • Although, configuring cryptography keys are optional, at least 1 from the list of 3 should be provided, in order cryptography to be done
  • If null is provided for key1, key2 and key3, the current settings will be erased
  • On SheLr.GetConfig the keys themselves are never returned; instead key1, key2, key3 are booleans indicating whether each slot is set

SheLr instance address addr:

  • The size of the address should be 8 symbols (4 bytes), represented as a hexadecimal string
  • The upper 16 bits encode the group and the lower 16 bits encode the device within the group (e.g. "00010042" = group 0x0001, device 0x0042)
  • The address should be a unicast value (group ≠ "FFFF" and device ≠ "FFFF"). Configuring a multicast (*FFFF) or the broadcast (FFFFFFFF) value as the device's own address is accepted by SheLr.SetConfig for backwards compatibility, but the device will then be unable to receive unicast traffic addressed to itself — only multicast/broadcast frames matching that pattern. Avoid such values
  • If null is provided the last 2 bytes of the Wi-Fi MAC will be used as the device id portion, with the group set to 0x0000

Payload types (accept):

  • user — required to send/receive SheLr.Send frames
  • rpc — required to send/receive SheLr.Call and SheLr.Notify frames
  • Both the sender and the receiver must include the relevant payload type in accept; otherwise the frame is rejected (on TX with an error, on RX it is silently dropped after decryption)
  • An empty list (or null) disables all SheLR payload handling for the instance

Status​

SheLr.GetStatus currently exposes only the instance id:

PropertyTypeDescription

id

number

Id of the SheLr instance

LoRa-radio level traffic counters, duty-cycle state and add-on availability live on the LoRa (radio) component — see LoRa.GetStatus.

Notifications​

This notification is triggered when a user payload is received over LoRa RF using SheLR, sent by SheLr.Send. It is emitted on the SheLr instance that successfully decrypted the frame (component: "shelr:<id>").

  • method: "NotifyEvent"
  • event: "user_rx"
    PropertyTypeDescription

    data

    string

    Received data (remark: encoded in 'base64')

    sender

    string

    Sender address as a hexadecimal string (the sender's addr)

    rssi

    number

    RSSI of the received packet

    snr

    number

    SNR (signal / noise ratio) of the received packet

    tsu

    number

    LoRa add-on uptime in ms

Example: Notifications Example​

Examples​

SheLr.Create Example​

http://192.168.33.1/rpc/SheLr.Create?config={"name":"main","addr":"000000BA","tx_key_id":2,"key1":null,"key2":"MTIzNDU2Nzg5MEFCQ0RFRg==","key3":"cRIzRJVmd4iZqrvM3e7/AA==","accept":["user","rpc"]}

Response

{
"id": 200
}

SheLr.Delete Example​

http://192.168.33.1/rpc/SheLr.Delete?id=200

Response

null

SheLr.GetConfig Example​

http://192.168.33.1/rpc/SheLr.GetConfig?id=200

Response

{
"id": 200,
"name": "main",
"addr": "000000BA",
"tx_key_id": 2,
"key1": false,
"key2": true,
"key3": true,
"accept": [
"user",
"rpc"
]
}

SheLr.SetConfig Example​

http://192.168.33.1/rpc/SheLr.SetConfig?id=200&config={"tx_key_id":3,"accept":["rpc"]}

Response

{
"restart_required": false
}

SheLr.GetStatus Example​

http://192.168.33.1/rpc/SheLr.GetStatus?id=200

Response

{
"id": 200
}

SheLr.Send Example​

http://192.168.33.1/rpc/SheLr.Send?id=200&lr_addr="00000063"&tx_key="MTIzNDU2Nzg5MEFCQ0RFRg=="&data="MTA="

Response

null

SheLr.Call Example​

http://192.168.33.1/rpc/SheLr.Call?id=200&lr_addr="00000063"&method="Switch.Set"&params={"id":0,"on":true}&tx_key_id=2

Response

{
"was_on": false
}

SheLr.Notify Example​

http://192.168.33.1/rpc/SheLr.Notify?id=200&lr_addr="FFFFFFFF"&method="Switch.Toggle"&params={"id":7}

Response

null

SheLr.ResetRxCounter Example​

http://192.168.33.1/rpc/SheLr.ResetRxCounter?id=200&lr_addr="00000063"

Response

null

Notifications Example​

When a user payload is received over LoRa RF using SheLR, sent by SheLr.Send:​

Notify data is received over LoRa RF using SheLR.
{
"src": "shelly1pmg3-dcda0ce0d36c",
"dst": "user_1",
"method": "NotifyEvent",
"params": {
"ts": 1631266595.43,
"events": [
{
"component": "shelr:200",
"id": 200,
"event": "user_rx",
"ts": 1631266595.43,
"info": {
"data": "MTA=",
"sender": "00000017",
"rssi": -70,
"snr": 8,
"tsu": 16212139809
}
}
]
}
}