Summary
This spec covers the Somfy Digital Network (SDN) RS-485 bus protocol as implemented by the Somfy ILT2 (and other Somfy RS-485 products sharing the same protocol). Communication is half-duplex, master/slave, framed, with a complement checksum and a 3-byte NodeID address. Each framed message carries a 1-byte MSG opcode, an ACK/LEN byte, a NodeType byte, a 3-byte SOURCE@, a 3-byte DEST@, a DATA payload, and a 2-byte complement checksum.
Transport
protocols:
- serial
serial:
baud_rate: 4800
data_bits: 8
parity: odd
stop_bits: 1
flow_control: none
character_coding: NRZ
electrical: RS-485 # half-duplex, master/slave bus
bit_order: LSBF # least significant bit sent first
inversion: data_bits_inverted_before_transmission # e.g. 58h transmitted as A7h
auth:
type: none # inferred: no auth procedure in source
Frame structure (11–32 bytes):
| Byte 1 | Byte 2 | Byte 3 | Bytes 4–6 | Bytes 7–9 | Bytes 10..n-2 | Bytes n-1..n |
|---|---|---|---|---|---|---|
| MSG | ACK/LEN | NodeType (src/dest) | SOURCE@ (3 bytes, LSBF) | DEST@ (3 bytes, LSBF) | DATA (0–21 bytes) | CHECKSUM (2 bytes, complement sum) |
Byte 2bits:ACK(b7) |EXT=0(b6..b5) |LEN(b4..b0)Byte 3bits:SRC NodeType(b7..b4) |DEST NodeType(b3..b0).SRC NodeType=0hfor master devices.- Addressing: point-to-point (DEST@=NodeID), group (DEST@=000000h, SOURCE@=GroupID), or broadcast (DEST@=FFFFFFh). NodeType filtering via DEST NodeType field.
- No port (RS-485 bus). No auth.
- Bus timings:
Tcmax 1 ms between characters,Tfree3 ms bus-free timeout,Trep5–255 ms (randomized) slave reply delay,Treq≥ 10 ms master pre-send delay.
Traits
- queryable # inferred: GET_xxx status request commands present
Actions
# Every MSG-classed message documented in the source is enumerated below as
# a separate action. POST/ACK/NACK responses are captured in Feedbacks.
# `command:` carries the MSG opcode and the DATA-length code; the surrounding
# frame (NodeType / SOURCE@ / DEST@ / CHECKSUM) is documented in Transport.
# For parameterized messages the DATA field layout is given in `params:`.
- id: ctrl_moveto
label: Move to Position
kind: action
command: "MSG=03h (CTRL_MOVETO) LEN=04h"
params:
- name: function
type: integer
description: 00h=down limit, 01h=up limit, 02h=intermediate position, 04h=position in %
- name: position
type: integer
description: 16-bit; IP index (0..15) for function 02h, % value (0..100) for function 04h, ignored otherwise
- name: reserved
type: integer
description: 8-bit, send 00h
- id: ctrl_stop
label: Stop
kind: action
command: "MSG=02h (CTRL_STOP) LEN=01h"
params:
- name: reserved
type: integer
description: 8-bit, send 00h
- id: set_motor_rolling_speed
label: Set Motor Rolling Speed (DC motors only)
kind: action
command: "MSG=13h (SET_MOTOR_ROLLING_SPEED) LEN=03h"
params:
- name: up_speed
type: integer
description: 8-bit; rpm during UP movement (range per device datasheet)
- name: down_speed
type: integer
description: 8-bit; rpm during DOWN movement (range per device datasheet)
- name: slow_speed
type: integer
description: 8-bit; rpm for adjustment movements (range per device datasheet)
- id: set_motor_ip
label: Set Intermediate Position
kind: action
command: "MSG=15h (SET_MOTOR_IP) LEN=04h"
params:
- name: function
type: integer
description: 00h=delete IP, 01h=set IP at current position, 03h=set IP at given %, 04h=divide full range
- name: ip_index
type: integer
description: 8-bit; 1..16
- name: value
type: integer
description: 16-bit; % for function 03h, IP count for function 04h, ignored for 00h/01h
- id: set_network_lock
label: Set Network Lock
kind: action
command: "MSG=16h (SET_NETWORK_LOCK) LEN=02h"
params:
- name: function
type: integer
description: 00h=Unlock, 01h=Lock, 03h=Save lock across power cycle, 04h=Do not save
- name: priority
type: integer
description: 8-bit; higher = higher priority; ignored for function 03h/04h
- id: set_local_ui
label: Set Local UI Lock
kind: action
command: "MSG=17h (SET_LOCAL_UI) LEN=03h"
params:
- name: function
type: integer
description: 00h=Enable/Unlock, 01h=Disable/Lock
- name: ui_index
type: integer
description: 00h=All local controls, 01h=DCT input, 02h=Local stimuli, 03h=Local radio (BT), 04h=Touch Motion, 05h=LEDs
- name: priority
type: integer
description: 8-bit; higher = higher priority
- id: set_node_label
label: Set Node Text Label
kind: action
command: "MSG=55h (SET_NODE_LABEL) LEN=10h"
params:
- name: label
type: string
description: 16 ASCII chars (pad with spaces if shorter)
- id: set_group_addr
label: Set Group Address
kind: action
command: "MSG=51h (SET_GROUP_ADDR) LEN=04h"
params:
- name: group_index
type: integer
description: 8-bit; 0..15
- name: group_id
type: integer
description: 24-bit NodeID-format group address (LSBF)
- id: get_node_addr
label: Get Node Address
kind: query
command: "MSG=40h (GET_NODE_ADDR) LEN=00h"
params: []
- id: get_group_addr
label: Get Group Address
kind: query
command: "MSG=41h (GET_GROUP_ADDR) LEN=01h"
params:
- name: group_index
type: integer
description: 8-bit; 0..15
- id: get_node_label
label: Get Node Text Label
kind: query
command: "MSG=45h (GET_NODE_LABEL) LEN=00h"
params: []
- id: get_node_app_version
label: Get Firmware Version
kind: query
command: "MSG=74h (GET_NODE_APP_VERSION) LEN=00h"
params: []
- id: get_motor_ip
label: Get Intermediate Position
kind: query
command: "MSG=25h (GET_MOTOR_IP) LEN=01h"
params:
- name: ip_index
type: integer
description: 8-bit; 1..16
- id: get_motor_rolling_speed
label: Get Motor Rolling Speed (DC motors only)
kind: query
command: "MSG=23h (GET_MOTOR_ROLLING_SPEED) LEN=00h"
params: []
- id: get_network_lock
label: Get Network Lock Status
kind: query
command: "MSG=26h (GET_NETWORK_LOCK) LEN=00h"
params: []
- id: get_local_ui
label: Get Local UI Lock Status
kind: query
command: "MSG=27h (GET_LOCAL_UI) LEN=01h"
params:
- name: ui_index
type: integer
description: 8-bit; 01h..UI_MAX (refer to SET_LOCAL_UI list)
- id: get_motor_position
label: Get Motor Position
kind: query
command: "MSG=0Ch (GET_MOTOR_POSITION) LEN=00h"
params: []
- id: get_motor_status
label: Get Motor Status
kind: query
command: "MSG=0Eh (GET_MOTOR_STATUS) LEN=00h"
params: []
Feedbacks
# Unsolicited and request-driven responses from the device.
- id: post_node_addr
label: Node Address Report
type: bytes
command: "MSG=60h (POST_NODE_ADDR) LEN=00h"
description: Slave replies with its NodeID; no DATA - address carried in header (SOURCE@).
- id: post_group_addr
label: Group Address Report
type: object
command: "MSG=61h (POST_GROUP_ADDR) LEN=04h"
fields:
- name: group_index
type: integer
description: 8-bit; 0..15
- name: group_id
type: integer
description: 24-bit group NodeID (LSBF)
- id: post_node_label
label: Node Text Label Report
type: string
command: "MSG=65h (POST_NODE_LABEL) LEN=10h"
description: 16 ASCII chars.
- id: post_node_app_version
label: Firmware Version Report
type: object
command: "MSG=75h (POST_NODE_APP_VERSION) LEN=06h"
fields:
- name: app_reference
type: integer
description: 24-bit; firmware part number
- name: app_index_letter
type: integer
description: 8-bit ASCII (41h..5Ah); firmware major revision letter
- name: app_index_number
type: integer
description: 8-bit; firmware revision
- name: reserved
type: integer
description: 8-bit
- id: post_local_ui
label: Local UI Lock Status Report
type: object
command: "MSG=37h (POST_LOCAL_UI) LEN=05h"
fields:
- name: status
type: enum
values: [enabled, disabled]
- name: source_addr
type: integer
description: 24-bit NodeID of the device that issued the lock (000000h when unlocked)
- name: priority
type: integer
description: 8-bit; 00h when unlocked
- id: post_motor_ip
label: Intermediate Position Report
type: object
command: "MSG=35h (POST_MOTOR_IP) LEN=04h"
fields:
- name: ip_index
type: integer
description: 8-bit; 1..16
- name: reserved
type: integer
description: 16-bit
- name: ip_position_percentage
type: integer
description: 8-bit; 0..100; FFh if IP not set
- id: post_motor_rolling_speed
label: Motor Rolling Speed Report (DC motors only)
type: object
command: "MSG=33h (POST_MOTOR_ROLLING_SPEED) LEN=03h"
fields:
- name: up_speed
type: integer
description: 8-bit
- name: down_speed
type: integer
description: 8-bit
- name: slow_speed
type: integer
description: 8-bit
- id: post_network_lock
label: Network Lock Status Report
type: object
command: "MSG=36h (POST_NETWORK_LOCK) LEN=06h"
fields:
- name: status
type: enum
values: [unlocked, locked]
- name: source_addr
type: integer
description: 24-bit NodeID of locker
- name: priority
type: integer
description: 8-bit
- name: saved
type: enum
values: [not_saved, saved]
description: Whether lock is restored on power cycle
- id: post_motor_position
label: Motor Position Report
type: object
command: "MSG=0Dh (POST_MOTOR_POSITION) LEN=05h"
fields:
- name: position_pulse
type: integer
description: 16-bit; raw position between UP_LIMIT and DOWN_LIMIT
- name: position_percentage
type: integer
description: 8-bit; 0..100
- name: reserved
type: integer
description: 8-bit
- name: ip
type: integer
description: 8-bit; current IP index (01h..IP_MAX), FFh if not at an IP
- id: post_motor_status
label: Motor Status Report
type: object
command: "MSG=0Fh (POST_MOTOR_STATUS) LEN=04h"
fields:
- name: status
type: enum
values: [stopped, running, blocked, locked]
description: 00h=Stopped, 01h=Running, 02h=Blocked (thermal/obstacle), 03h=Locked (NETWORK_LOCK)
- name: direction
type: enum
values: [down, up, unknown]
description: 00h=Down, 01h=Up, FFh=Unknown
- name: source
type: enum
values: [internal, network, local_ui]
description: Origin of last command
- name: cause
type: integer
description: 00h=Target reached, 01h=Explicit command, 02h=Wink, 20h=Obstacle, 21h=Over-current, 22h=Thermal, 30h=Run time exceeded, 32h=Timeout, FFh=Reset/PowerUp
- id: ack
label: Acknowledge
type: enum
values: [ok]
command: "MSG=7Fh (ACK) LEN=00h"
description: Sent by slave when ACK bit was set in the request and processing succeeded.
- id: nack
label: Negative Acknowledge / Error
type: object
command: "MSG=6Fh (NACK) LEN=01h"
fields:
- name: error_code
type: integer
description: 01h=Data out of range, 10h=Unknown message, 11h=Message length error, FFh=Busy/cannot process
Variables
# Persistent settings stored on the device; some are writable via Actions, all
# readable via the corresponding GET request and POST feedback.
- name: node_id
description: 3-byte built-in NodeID. Read-only; programmed at manufacturing.
- name: node_label
description: 16-char user text label. Writable via SET_NODE_LABEL.
- name: firmware_version
description: App_Reference (3 bytes) + App_IndexLetter (1 byte ASCII) + App_IndexNumber (1 byte). Read-only.
- name: group_membership
description: Up to 16 group table entries (GroupIndex 0..15) each holding a GroupID. Writable via SET_GROUP_ADDR.
- name: local_ui_locks
description: Per-UI lock state, source NodeID and priority for each UI_Index. Writable via SET_LOCAL_UI.
- name: motor_intermediate_positions
description: Up to 16 IPs (IP_Index 1..16) each with a position in 0..100%. Writable via SET_MOTOR_IP.
- name: motor_rolling_speeds
description: UP/DOWN/Slow rpm for DC motors. Writable via SET_MOTOR_ROLLING_SPEED.
- name: network_lock
description: Lock state, source NodeID, priority, and save-across-power-cycle flag. Writable via SET_NETWORK_LOCK.
Events
# No unsolicited push events are defined by this protocol. All device
# information is delivered only in response to a MASTER GET request.
# UNRESOLVED: source describes no event/notification messages.
Macros
# UNRESOLVED: source does not define multi-step sequences.
Safety
confirmation_required_for: []
interlocks:
- description: When NETWORK_LOCK is active, all CTRL_xxx movement commands and SET_MOTOR_LIMITS / SET_TILT_LIMITS are rejected with NACK(NODE_IS_LOCKED) unless the controlling message carries a priority equal to or higher than the active lock priority.
- description: When Local UI items are disabled/locked, all actions and feedback related to those items are ignored until re-enabled.
# UNRESOLVED: source contains no explicit electrical/installation safety warnings
# (wiring and topology guidance is in a separate document DOC114316 not in scope).
Notes
- This spec covers the SDN bus protocol in general. The Somfy ILT2 is one of the RS-485 devices that implements it; the spec is structurally applicable to any SDN node (NodeTypes 02h, 05h, 06h, 07h, 08h, 09h). Device-specific capabilities (e.g. rolling speed is "DC motors only") vary per NodeType.
- Data bits are inverted before transmission for backward compatibility with earliest protocol versions (e.g.
58hon the wire =NOT(58h) = A7h). Every byte in the frame (MSG, ACK/LEN, NodeType, SOURCE@, DEST@, DATA, checksum) must be inverted on transmit and de-inverted on receive. - SOURCE@ and DEST@ are LSBF (least significant byte first).
- Frame bytes are 11..32; DATA length 0..21. Reserved fields should be set to
00horFFh. CHECKSUM= 2-byte complement sum of bytes 1..n-2:CHECKSUM = (Byte 1 + ... + Byte n-2) complement. No error correction; consider retries on NACK or ACK timeout.- ACK bit in
Byte 2is set by the master when an acknowledgement is required. Status requests do not produce ACK; the POST_xxx reply is the feedback. - Avoid requesting feedback (ACK or POST) in group or broadcast addressing to lower collision risk.
- MOTOR_IP function
04h("divide full range with given number of IPs") distributes IPs equally between top and bottom limits. Example: 2 IPs → IP1=33%, IP2=66%. Existing IPs are overwritten. SET_MOTOR_IPfunction02his not listed in the source table (only 00h, 01h, 03h, 04h are documented). Treat 02h as reserved unless the device datasheet states otherwise.- For
SET_MOTOR_IPfunction04hthe source saysIP_Index is ignored, so the IP_Index byte in the frame should be sent as00h. CTRL_STOPhalts the motor immediately without speed ramp-down.- POST_MOTOR_POSITION may be sent while the motor is running; the
IPfield returnsFFhwhen the position does not match any defined IP (with a small tolerance that is motor-dependent).
Provenance
source_domains:
- service.somfy.com
source_urls:
- https://service.somfy.com/downloads/bui_v4/sdn-integration-guide--preliminary.pdf
retrieved_at: 2026-06-02T05:04:19.396Z
last_checked_at: 2026-06-02T22:14:46.075Z
Verification Summary
verdict: verified
checked_at: 2026-06-02T22:14:46.075Z
matched_actions: 18
action_count: 18
confidence: medium
summary: "All 18 spec actions traced to source (dip-safe re-verify). (9 unresolved item(s) noted in Known Gaps.)"
Known Gaps
- "speed ranges for SET_MOTOR_ROLLING_SPEED depend on the device technical datasheet, not included in this source."
- "minimum/typical uptime values and wiring constraints come from a separate document (DOC114316) not included here."
- "device is a motor controller; movement commands (UP/DOWN/Stop/MoveTo) are not classified as `powerable`, `routable`, or `levelable` per the AI4AV trait taxonomy."
- "source describes no event/notification messages."
- "source does not define multi-step sequences."
- "source contains no explicit electrical/installation safety warnings"
- "speed min/max ranges for SET_MOTOR_ROLLING_SPEED are device-specific; refer to the device technical datasheet."
- "bus topology, cable lengths, and wiring constraints are in DOC114316 \"SDN Bus Wiring Guide\", not in this source."
- "any safety / installation warnings in DOC114316 are not captured here."
From the AI4AV catalog (https://ai4av.net) · ODbL-1.0