Summary
The Tyba Turn 2 is a wall-mounted rotary-dial control platform for lighting, shades, climate, and media, exposed via a public REST API served on each Turn device at http://{host}:55555/api/v1.0/ returning JSON. Control is organized around pages and channels; each channel (e.g. light/1/1) carries state (value, on) modifiable by GET/PUT on /control/channels/{channelId}/state plus POST actions, with SSE feeds (/control/events/...) for subscriptions. This spec covers the public API documented in "Turn 2 Public API Documentation (1.4.4)"; the private API (page configuration, network settings) is out of scope.
Transport
protocols:
- http
addressing:
base_url: "http://{host}:55555/api/v1.0/"
port: 55555
auth:
type: none # inferred: no auth procedure in source. All requests DO require a "Sender-Id" header (any non-empty string) for event-source identification, not authentication.
Traits
# Add only traits supported by evidence from source:
traits:
- queryable # inferred from GET state/channel/config endpoints
- levelable # inferred from percentage/temperature setpoint channels (lights, shades, volume, climate setpoints)
Actions
# --- Core channel endpoints ---
- id: get_all_channels
label: Get All Channels
kind: query
command: "GET /api/v1.0/control/channels"
params: []
- id: get_channels_by_type
label: Get Channels by Channel Type
kind: query
command: "GET /api/v1.0/control/channels/{channelType}"
params:
- name: channelType
type: string
description: "Channel type e.g. light, shade, fan, modes, current_temperature, media_volume"
- id: get_channels_by_page
label: Get Channels by Page
kind: query
command: "GET /api/v1.0/control/channels/{pageId}"
params:
- name: pageId
type: string
description: "Page id e.g. light/1"
- id: get_channel
label: Get Channel by Id
kind: query
command: "GET /api/v1.0/control/channels/{channelId}"
params:
- name: channelId
type: string
description: "Channel id e.g. light/1/1"
- id: get_channel_state
label: Get Channel State
kind: query
command: "GET /api/v1.0/control/channels/{channelId}/state"
params:
- name: channelId
type: string
description: "Channel id e.g. light/1/1"
- id: set_channel_state
label: Set Channel State
kind: action
command: "PUT /api/v1.0/control/channels/{channelId}/state"
body: '{"value": 50, "on": true}'
params:
- name: channelId
type: string
description: "Channel to modify"
- name: value
type: integer
description: "State value per channel data type (percentage 0-100, temperature 0-212, preset 0-8); send value OR on"
- name: on
type: boolean
description: "Switch state; send on OR value"
- id: get_channel_actions
label: Get Channel Actions
kind: query
command: "GET /api/v1.0/control/channels/{channelId}/action/"
params:
- name: channelId
type: string
description: "Channel id e.g. light/1/1 (returns e.g. [\"increment_decrement\"])"
- id: post_channel_action
label: Post Channel Action
kind: action
command: "POST /api/v1.0/control/channels/{channelId}/action"
body: '{"increment_decrement": 0}'
params:
- name: channelId
type: string
description: "Channel to modify"
- name: action_payload
type: integer
description: "Payloads are either 0 or 1; key is the action name e.g. increment_decrement, play_action, pause_action"
# --- Per-channel semantic actions (Table 6 rows; light/shade pages 1-5 parameterized as in source) ---
- id: set_light_value
label: Set Light Level
kind: action
command: "PUT /api/v1.0/control/channels/light/{page}/1/state"
body: '{"value": {level}}'
params:
- name: page
type: integer
description: "Light page 1-5"
- name: level
type: integer
description: "Percentage 0-100"
- id: set_light_on
label: Set Light On/Off
kind: action
command: "PUT /api/v1.0/control/channels/light/{page}/1/state"
body: '{"on": {bool}}'
params:
- name: page
type: integer
description: "Light page 1-5"
- name: bool
type: boolean
description: "true/false"
- id: light_increment_decrement
label: Light Increment/Decrement
kind: action
command: "POST /api/v1.0/control/channels/light/{page}/1/action"
body: '{"increment_decrement": {dir}}'
params:
- name: page
type: integer
description: "Light page 1-5"
- name: dir
type: integer
description: "0 for decrement, 1 for increment"
- id: set_shade_value
label: Set Shade Position
kind: action
command: "PUT /api/v1.0/control/channels/shade/{page}/1/state"
body: '{"value": {level}}'
params:
- name: page
type: integer
description: "Shade page 1-5"
- name: level
type: integer
description: "Percentage 0-100"
- id: set_shade_on
label: Set Shade On/Off
kind: action
command: "PUT /api/v1.0/control/channels/shade/{page}/1/state"
body: '{"on": {bool}}'
params:
- name: page
type: integer
description: "Shade page 1-5"
- name: bool
type: boolean
description: "true/false"
- id: shade_increment_decrement
label: Shade Increment/Decrement
kind: action
command: "POST /api/v1.0/control/channels/shade/{page}/1/action"
body: '{"increment_decrement": {dir}}'
params:
- name: page
type: integer
description: "Shade page 1-5"
- name: dir
type: integer
description: "0 for decrement, 1 for increment"
- id: set_light_scenes_preset
label: Set Light Scenes Preset
kind: action
command: "PUT /api/v1.0/control/channels/light_scenes/1/1/state"
body: '{"value": {preset}}'
params:
- name: preset
type: integer
description: "Preset 0-8"
- id: set_light_scenes_on
label: Set Light Scenes On/Off
kind: action
command: "PUT /api/v1.0/control/channels/light_scenes/1/1/state"
body: '{"on": {bool}}'
params:
- name: bool
type: boolean
description: "true/false"
- id: light_scenes_increment_decrement
label: Light Scenes Increment/Decrement
kind: action
command: "POST /api/v1.0/control/channels/light_scenes/1/1/action"
body: '{"increment_decrement": {dir}}'
params:
- name: dir
type: integer
description: "0 for decrement, 1 for increment"
- id: set_shade_scenes_preset
label: Set Shade Scenes Preset
kind: action
command: "PUT /api/v1.0/control/channels/shade_scenes/1/1/state"
body: '{"value": {preset}}'
params:
- name: preset
type: integer
description: "Preset 0-8"
- id: set_shade_scenes_on
label: Set Shade Scenes On/Off
kind: action
command: "PUT /api/v1.0/control/channels/shade_scenes/1/1/state"
body: '{"on": {bool}}'
params:
- name: bool
type: boolean
description: "true/false"
- id: shade_scenes_increment_decrement
label: Shade Scenes Increment/Decrement
kind: action
command: "POST /api/v1.0/control/channels/shade_scenes/1/1/action"
body: '{"increment_decrement": {dir}}'
params:
- name: dir
type: integer
description: "0 for decrement, 1 for increment"
- id: set_temperature_setpoint
label: Set Temperature Setpoint
kind: action
command: "PUT /api/v1.0/control/channels/temperature/1/1/state"
body: '{"value": {temp}}'
params:
- name: temp
type: number
description: "Temperature 0-212"
- id: temperature_increment_decrement
label: Temperature Setpoint Increment/Decrement
kind: action
command: "POST /api/v1.0/control/channels/temperature/1/1/action"
body: '{"increment_decrement": {dir}}'
params:
- name: dir
type: integer
description: "0 for decrement, 1 for increment"
- id: set_humidity_setpoint
label: Set Humidity Setpoint
kind: action
command: "PUT /api/v1.0/control/channels/humidity/1/1/state"
body: '{"value": {level}}'
params:
- name: level
type: integer
description: "Percentage 0-100"
- id: humidity_increment_decrement
label: Humidity Setpoint Increment/Decrement
kind: action
command: "POST /api/v1.0/control/channels/humidity/1/1/action"
body: '{"increment_decrement": {dir}}'
params:
- name: dir
type: integer
description: "0 for decrement, 1 for increment"
- id: set_fan_preset
label: Set Fan Preset
kind: action
command: "PUT /api/v1.0/control/channels/fan/1/1/state"
body: '{"value": {preset}}'
params:
- name: preset
type: integer
description: "Preset 0-8"
- id: set_fan_on
label: Set Fan On/Off
kind: action
command: "PUT /api/v1.0/control/channels/fan/1/1/state"
body: '{"on": {bool}}'
params:
- name: bool
type: boolean
description: "true/false"
- id: fan_increment_decrement
label: Fan Increment/Decrement
kind: action
command: "POST /api/v1.0/control/channels/fan/1/1/action"
body: '{"increment_decrement": {dir}}'
params:
- name: dir
type: integer
description: "0 for decrement, 1 for increment"
- id: set_modes_preset
label: Set Mode
kind: action
command: "PUT /api/v1.0/control/channels/modes/1/1/state"
body: '{"value": {preset}}'
params:
- name: preset
type: integer
description: "Preset index; names configured per device (example: Off,Heat,Cool,Away,Home)"
- id: set_modes_on
label: Set Modes On/Off
kind: action
command: "PUT /api/v1.0/control/channels/modes/1/1/state"
body: '{"on": {bool}}'
params:
- name: bool
type: boolean
description: "true/false"
- id: modes_increment_decrement
label: Modes Increment/Decrement
kind: action
command: "POST /api/v1.0/control/channels/modes/1/1/action"
body: '{"increment_decrement": {dir}}'
params:
- name: dir
type: integer
description: "0 for decrement, 1 for increment"
- id: set_media_volume
label: Set Media Volume
kind: action
command: "PUT /api/v1.0/control/channels/media/1/1/state"
body: '{"value": {level}}'
params:
- name: level
type: integer
description: "Percentage 0-100"
- id: media_volume_increment_decrement
label: Media Volume Increment/Decrement
kind: action
command: "POST /api/v1.0/control/channels/media/1/1/action"
body: '{"increment_decrement": {dir}}'
params:
- name: dir
type: integer
description: "0 for decrement, 1 for increment"
- id: set_media_play_pause
label: Set Media Play/Pause
kind: action
command: "PUT /api/v1.0/control/channels/media/1/2/state"
body: '{"value": {bool}}'
params:
- name: bool
type: boolean
description: "true for play, false for pause (method 1)"
- id: media_play_action
label: Media Play Action
kind: action
command: "POST /api/v1.0/control/channels/media/1/2/action"
body: '{"play_action": "1"}'
params: []
- id: media_pause_action
label: Media Pause Action
kind: action
command: "POST /api/v1.0/control/channels/media/1/2/action"
body: '{"pause_action": "1"}'
params: []
- id: set_media_play_stop
label: Set Media Play/Stop
kind: action
command: "PUT /api/v1.0/control/channels/media/1/3/state"
body: '{"value": {bool}}'
params:
- name: bool
type: boolean
description: "true=play, false=stop; playing requires media/1/3 true AND media/1/4 false (method 3)"
- id: set_media_pause_unpause
label: Set Media Pause/Unpause
kind: action
command: "PUT /api/v1.0/control/channels/media/1/4/state"
body: '{"value": {bool}}'
params:
- name: bool
type: boolean
description: "false=unpaused; playing requires media/1/3 true AND media/1/4 false (method 3)"
- id: set_media_skip
label: Media Next/Previous
kind: action
command: "PUT /api/v1.0/control/channels/media/1/5/state"
body: '{"value": {payload}}'
params:
- name: payload
type: string
description: "media_transport_skip channel, dataType action (string payload). UNRESOLVED: exact payload values for next vs previous not stated in source"
- id: set_media_mute
label: Set Media Mute
kind: action
command: "PUT /api/v1.0/control/channels/media/1/6/state"
body: '{"value": {bool}}'
params:
- name: bool
type: boolean
description: "true/false switch"
- id: set_source_select
label: Select Media Source
kind: action
command: "PUT /api/v1.0/control/channels/source/1/1/state"
body: '{"value": {preset}}'
params:
- name: preset
type: integer
description: "Preset index selecting one of up to 8 configured sources"
# --- Global state ---
- id: get_all_control_states
label: Get All Control States
kind: query
command: "GET /api/v1.0/control/state"
params: []
- id: put_control_state
label: Put Control State
kind: action
command: "PUT /api/v1.0/control/state"
body: '{"ready": "false"}'
params:
- name: state_key
type: string
description: "Control state key to set e.g. ready"
- id: get_internal_temperature
label: Get Internal Temperature
kind: query
command: "GET /api/v1.0/control/state/internal_temperature"
params: []
- id: get_internal_temperature_value
label: Get Internal Temperature Value
kind: query
command: "GET /api/v1.0/control/state/internal_temperature/value"
params: []
- id: get_internal_temperature_fahrenheit
label: Get Internal Temperature Fahrenheit
kind: query
command: "GET /api/v1.0/control/state/internal_temperature/fahrenheit"
params: []
- id: global_action_reset
label: Global Reset
kind: action
command: "POST /api/v1.0/control/action/reset"
params: []
# resets all control states and channels to their initial state
# --- Config ---
- id: get_config
label: Get Config
kind: query
command: "GET /api/v1.0/config"
params: []
- id: get_config_version
label: Get Config Version
kind: query
command: "GET /api/v1.0/config/version"
params: []
- id: get_integrations
label: Get Integrations
kind: query
command: "GET /api/v1.0/integrations"
params: []
# --- SSE subscriptions ---
- id: subscribe_all_channel_events
label: Subscribe All Channel Events
kind: query
command: "GET /api/v1.0/control/events/channels"
params: []
- id: subscribe_channel_events_by_type
label: Subscribe Channel Events by Type
kind: query
command: "GET /api/v1.0/control/events/channels/{channelType}"
params:
- name: channelType
type: string
description: "The channel type"
- id: subscribe_channel_events_by_page
label: Subscribe Channel Events by Page
kind: query
command: "GET /api/v1.0/control/events/channels/{channelIndex}"
params:
- name: channelIndex
type: string
description: "The channel type/index to listen to"
- id: subscribe_channel_events_by_id
label: Subscribe Channel Events by Id
kind: query
command: "GET /api/v1.0/control/events/channels/{channelId}"
params:
- name: channelId
type: string
description: "The channel to listen to"
- id: subscribe_all_control_state_events
label: Subscribe All Control State Events
kind: query
command: "GET /api/v1.0/control/events/state"
params: []
- id: subscribe_control_state_events_by_state
label: Subscribe Control State Events by State
kind: query
command: "GET /api/v1.0/control/events/state/{state}"
params:
- name: state
type: string
description: "The state to listen to e.g. internal_temperature"
- id: subscribe_config_events
label: Subscribe Config Events
kind: query
command: "GET /api/v1.0/config/events"
params: []
Feedbacks
- id: channel_state
type: object
values: [value, on]
description: "Per-channel state mapping e.g. {\"value\": 0, \"on\": \"false\"}; retrieved via GET /control/channels/{channelId}/state"
- id: current_temperature
type: number
description: "temperature/1/2 current_temperature channel, dataType temperature 0-212"
- id: current_humidity
type: number
description: "humidity/1/2 current_humidity channel, dataType percentage 0-100"
- id: air_quality
type: string
description: "info/1/1 ppm_string endpoint; value rounded half-up and appended with \"ppm\""
- id: air_pressure
type: string
description: "info/2/1 pa_string endpoint; value rounded half-up and appended with \"Pa\""
- id: media_artwork
type: string
description: "source/1/2 media_artwork channel, image URL string"
- id: media_metadata_artist
type: string
description: "source/1/3 media_metadata channel (Artist)"
- id: media_metadata_track
type: string
description: "source/1/4 media_metadata channel (Track)"
- id: internal_temperature
type: object
description: "{\"value\": \"0.0\", \"fahrenheit\": \"32.0\"}"
- id: internal_temperature_fahrenheit
type: number
description: "{\"fahrenheit\": \"32.0\"}"
- id: all_control_states
type: object
description: "GET /control/state e.g. {\"internal_temperature\": 0}"
- id: config
type: object
description: "Page configuration from GET /config (pages, channels, sources)"
- id: config_version
type: string
description: "Feature/version indicator e.g. \"2.0.0\"; corresponds to API documentation version"
Variables
- id: light_level
type: integer
range: "0-100"
description: "Per light page (light/1/1 .. light/5/1), percentage"
- id: shade_position
type: integer
range: "0-100"
description: "Per shade page (shade/1/1 .. shade/5/1), percentage"
- id: temperature_setpoint
type: number
range: "0-212"
description: "temperature/1/1 setpoint_temperature"
- id: humidity_setpoint
type: integer
range: "0-100"
description: "humidity/1/1 setpoint_humidity, percentage"
- id: media_volume
type: integer
range: "0-100"
description: "media/1/1 media_volume, percentage"
- id: fan_preset
type: integer
range: "0-8"
description: "fan/1/1 preset"
- id: modes_preset
type: integer
range: "0-8"
description: "modes/1/1 preset; count/names per device config"
- id: light_scenes_preset
type: integer
range: "0-8"
description: "light_scenes/1/1 preset"
- id: shade_scenes_preset
type: integer
range: "0-8"
description: "shade_scenes/1/1 preset"
- id: source_select
type: integer
range: "0-8"
description: "source/1/1 preset; up to 8 selectable sources"
Events
- id: channel_state_changed
description: "SSE push on channel state change; subscribe via /control/events/channels (all), /{channelType}, /{channelIndex}, or /{channelId}. Events carry the Sender-Id of the originator"
- id: control_state_changed
description: "SSE push on global control state change; subscribe via /control/events/state or /control/events/state/{state} (e.g. internal_temperature)"
- id: config_updated
description: "SSE config update notification; subscribe via /config/events"
- id: heartbeat
description: "All SSE endpoints emit a heartbeat comment (`: heartbeat`) every 30 seconds; ignore or use for connection health monitoring"
Macros
# UNRESOLVED: no multi-step sequences explicitly described in source
Safety
confirmation_required_for: []
interlocks: []
# UNRESOLVED: no safety warnings, interlock procedures, or power-on sequencing
# requirements found in source
Notes
- All HTTP requests require a
Sender-Idheader (any non-empty string, exampleTybaHome). It is echoed in SSE events so clients can ignore self-originated events and avoid feedback loops. - Three synchronized play/pause methods exist for transport sources: (1)
media/1/2value true/false; (2)play_action/pause_actionPOST actions with payload"1"onmedia/1/2; (3)media/1/3(play/stop) true ANDmedia/1/4(pause/unpause) false = playing. Pick one; all stay in sync. - Channel endpoints stay synchronized: setting
value0→20 also flipsonto true. increment_decrementpayload: 0 = decrement, 1 = increment.ppm_string/pa_stringendpoints accept string/int/float, round half-up to integer, return string suffixed "ppm"/"Pa".- Page limits: light/shade pages 0-5 each, scenes 0-1, climate pages 0-1, media 0-1. Sources page lists up to 8 sources (config
sourcesproperty: name, power, transport, controlType main_bus|sonos). - API is split public (this spec) / private (page configuration, network settings, sleep timeout — not documented here).
- API documentation version 1.4.4;
GET /config/versionreports config feature version (e.g. "2.0.0"). - Sonos integration exposed at
/api/v1.0/integrations; includes endpoint for next/previous transport-controls enabled status.
Provenance
source_domains:
- cloud.tybahome.com
source_urls:
- https://cloud.tybahome.com:51443/apis/rest/v1.0/artifacts/latest/turnapp/Tyba_TY-K-TURN_Public_REST_API_Documentation
retrieved_at: 2026-07-17T02:45:35.193Z
last_checked_at: 2026-08-28T22:17:21.678Z
Verification Summary
verdict: verified
checked_at: 2026-08-28T22:17:21.678Z
matched_actions: 56
action_count: 56
confidence: medium
summary: "All 56 spec actions match documented endpoints, Table 5/6 control-endpoint cells and payload shapes; transport port 55555 and base path verbatim. (10 unresolved item(s) noted in Known Gaps.)"
Known Gaps
- "error response formats / status codes beyond 200 not documented in source"
- "rate limits, request timeouts not stated in source"
- "Sonos integration endpoint response schema only described in prose, example not shown in source"
- "exact payload values for next vs previous not stated in source\""
- "no multi-step sequences explicitly described in source"
- "no safety warnings, interlock procedures, or power-on sequencing"
- "firmware version compatibility not stated in source"
- "media/1/5 (next/prev) payload values not stated in source"
- "HTTP error status codes and error body schema not documented in source"
- "private API endpoints not documented in this source"
From the AI4AV catalog (https://ai4av.net) · ODbL-1.0