NAV
lua

License, Copyright, and Trademark

The content contained in this repository is the intellectual property of Snap One, LLC, (formerly known as Wirepath Home Systems, LLC), and use without a valid license from Snap One is strictly prohibited. The user of this repository shall keep all content contained herein confidential and shall protect this content in whole or in part from disclosure to any and all third parties except as specifically authorized in writing by Snap One.

License and Intellectual Property Disclaimer

The content in this repository is provided in connection with Snap One products. No license, express or implied, by estoppal or otherwise, to any intellectual property rights is granted by this document or in this repository. Except as provided in Snap Oneʼs terms and conditions for the license of such products, Snap One and its affiliates assume no liability whatsoever and disclaim any express or implied warranty, relating to the sale and/or use of Snap One products including liability or warranties relating to fitness for a particular purpose, merchantability, or infringement of any patent, copyright or other intellectual property right. Snap One products are not intended for use in medical, lifesaving, or life sustaining applications.

Information regarding third-party products is provided solely for educational purposes. Snap One is not responsible for the performance or support of third-party products and does not make any representations or warranties whatsoever regarding the quality, reliability, functionality or compatibility of these products. The reader is advised that third parties can have intellectual property rights that can be relevant to this repository and the technologies discussed herein, and is advised to seek the advice of competent legal counsel regarding the intellectual property rights of third parties, without obligation of Snap One.

Snap One retains the right make changes to this repository or related product specifications and descriptions in this repository, at any time, without notice. Snap One makes no warranty for the use of this repository and assumes no responsibility for any errors that can appear in the repository nor does it make a commitment to update the content contained herein.

Copyright

Copyright 2025 Snap One, LLC. All rights reserved.

The above copyright notice applies to all content in this repository unless otherwise stated explicitly herein that a third-party’s copyright applies.

No part of this publication may be reproduced, photocopied, stored on a retrieval system, or transmitted without the express written consent of the publisher.

Trademarks

Snap One and Snap One Logo, Control4 and the Control4 logo, and DriverWorks are trademarks or registered trademarks of Snap One, LLC. Other product and company names mentioned in this repository may be the trademarks or registered trademarks of their respective owners.

 Derivative Works

To the extent that you create any “Derivative Work” (meaning any work that is based upon one or more preexisting versions of the work provided to you in this repository, such as an enhancement or modification, revision, translation, abridgement, condensation, expansion, collection, compilation or any other form in which such preexisting works may be recast, modified, transformed or adapted, explicitly including without limitation, any updates or changes to Snap One, LLC’s software code or intellectual property) such Derivative Work shall be owned by Snap One, LLC and all right, title and interest in and to each such Derivative Work shall automatically vest in Snap One, LLC. To the extent any Derivative Work does not automatically vest in Snap One, LLC by operation of law, you hereby assign such Derivative Work to Snap One, LLC with full title guarantee. Snap One, LLC shall have no obligation to grant you any right in any such Derivative Work.

Contact Us

Snap One, LLC 11734 S. Election Road Salt Lake City, UT 84020 USA

http://www.control4.com

Introduction

This documentation includes content that details the functions that make up the Blind Control Proxy which is supported in the DriverWorks Software Development Kit.

Proxies (Commands)

A proxy driver is an interface to the Control4 system for a set of devices that share common functionality. For instance, most DVD disc changers have common controls such as SET LEVEL TARGET and SET MOVEMENT.  The blind proxy allows for a common user interface to control all blind controllers.  The Control4 system (Director) sends information to and receives information from the proxy drivers.  The proxy drivers send information to and receives information from the protocol drivers. Remember, your DriverWorks driver interacts with the proxy driver which then interacts with the system.  As a driver developer you will be relying on this proxy to provide status (notification) to the Control4 system for the device you are controlling.  You will also receive commands from the system that you will act on to control the device.  These commands and notifications are at the heart of what you will be implementing in your driver.  Essentially your driver is becoming the go-between from the Control4 system and your device with the proxy driver giving structure to the commands and notifications which you will be implementing. Your driver can facilitate communications with multiple types of proxies for a single device. As an example, a Security System driver will utilize both the Security proxy and the Contacts proxy. These additional proxies are configured in the <connections> section of the .c4z.

Protocol (Notifications)

Two similar devices may have the same functionality but utilize a very different command set.  A protocol driver provides the device-specific information needed to communicate with the Control4 system.  In the case of DriverWorks, the DriverWorks driver is the protocol driver.  When combined with the device-specific.c4Z file it provides the custom code necessary to implement the 2-way device driver. In the case of DriverWorks, the DriverWorks driver is the protocol driver. When combined with the device-specific.c4Z file it provides the custom code necessary to implement the 2-way device driver.

What’s New

What’s New in 3.4.2

There were no modifications to the Blind Control Proxy in conjunction with O.S. Release 3.4.2.

What’s New in 3.4.1

There were no modifications to the Blind Control Proxy in conjunction with O.S. Release 3.4.1.

What’s New in 3.4.0

Blind Proxy

A new capability has been added to the proxy called always_send_level. If value is true, then the SetTargetLevel commands are always sent regardless of current level values. This is useful if the blind device does not support two-way communication and is controlled outside of the Control4 operating system.

What’s New in 3.3.2

There were no modifications to the Blind Control Proxy in conjunction with O.S. Release 3.3.2.

What’s New in 3.3.1

There were no modifications to the Blind Control Proxy in conjunction with O.S. Release 3.3.1.

What’s New in 3.3.0

There were no modifications to the Blind Control Proxy in conjunction with O.S. Release 3.3.0.

What’s New in 3.2.3

There were no modifications to the Blind Control Proxy in conjunction with O.S. Release 3.2.3.

What’s New in 3.2.2

There were no modifications to the Blind Control Proxy in conjunction with O.S. Release 3.2.2

What’s New in 3.2.1

There were no modifications to the Blind Control Proxy in conjunction with O.S. Release 3.2.1.

What’s New in 3.2.0

There were no modifications to the Blind Control Proxy in conjunction with O.S. Release 3.2.0.

What was New in 3.1.2

There were no modifications to the Blind Control Proxy in conjunction with O.S. Release 3.1.2.

What was New in 3.1.0

There were no modifications to the Blind Control Proxy in conjunction with O.S. Release 3.1.0.

What was New in O.S.3

There were no modifications to the Blind Control Proxy in conjunction with O.S. Release 3.0.0.

Blind Proxy Commands

SET_LEVEL_TARGET

Requests a blind to go to a different position.

Name

SET_LEVEL_TARGET ()

Parameter Type Description
LEVEL_TARGET INT Integer of level that includes or is between level closed and level open (or level open + level closed secondary if level closed secondary is used).
Level_Target_Nam STR String of the level value, such as Open, Closed, Secondary Closed

Returns

None

SET_MOVEMENT

Name

SET_MOVEMENT ()

Parameter Type Description
SET\_MOVEMENT NUM Enumeration of the blind movement.

Returns

None

SET_TYPE

Sets the blind type for the proxy.

Name

SET_TYPE ()

Parameter Type Description
SET_Type NUM Enumeration of the blind type.

Blind Types:

If set to -1 then a dealer can select a choice from a pulldown in the proxy property control. This Notification sends DataToUI of blind setup xml.

Returns

None

Blind Protocol Notifications

SET_CAN_STOP

Configuration Notification used by the protocol to inform the proxy if the blind supports stopping or not.

Name

SET_CAN_STOP ()

Parameter Type Description
SET_CAN_STOP BOOL A boolean indicating if the blind control supports stop.

Returns

None

Usage Note

The blind level will be sent to the UI using a DataToUI as set can_stop_click = boolean. This Notification sends DataToUI of: blind_setup xml.

SET_HAS_LEVEL

Configuration Notification used by the protocol to inform the proxy that the driver does or does not support level control.

Name

SET_HAS_LEVEL ()

Parameter Type Description
HAS LEVEL bool Boolean indicating if level support is available
LEVEL OPEN int Open value. Blinds without feedback, regardless of stop support, should use 0.
LEVEL CLOSED int Closed value. Blinds without feedback and without a stop function should use 1.  Blinds without feedback but with stop function should use 2 as the value of 1 is to indicate an unknown state in the case that someone pressed up or down and then pressed stop before the blind was able to get to the target open/close state.
HAS LEVEL CLOSED SECONDARY bool Boolean indicating if the blind is using a secondary closed level
LEVEL CLOSED SECONDARY int Secondary closed value for blinds that can go both directions from an Open state.
LEVEL DISCRETE CONTROL bool Boolean indicating if the blind control has discrete level input. If false a UI will only send the specific level_closed and level_open values to the proxy/driver but a driver can still notify of various levels interpolated based on movement duration/time in each direction or using another formula. If true, the driver should support all level values in the range.  This could be discrete percentages or even include using level values of 1,2,3,... to execute presets but the driver should always be developed for close (level_close) and open (level_open) levels respectively.

Returns

None

Usage Note

All parameters are optional. This Notification sends DataToUI of: blind_setup xml.

SET_MOVEMENT

Configuration Notification used by the protocol to inform the proxy that the driver is a particular blind movement function.  If this is used, the proxy will disable the pull-down from being select-able by a dealer.

Name

SET_MOVEMENT ()

Parameter Type Description
SET MOVEMENT INT Enumeration of the blind movement type.

Movement Types:

If set to -1 then a dealer can again select a choice from a pull-down in the proxy property control.

Returns

None

Usage Note

This Notification sends DataToUI of: blind_setup xml.

SET_TYPE

Configuration Notification used by the protocol to inform the proxy that the driver is a particular blind type.  If this is used, the proxy will disable the pulldown from being selectable by a dealer.

Name

SET_TYPE ()

Parameter Type Description
SET TYPE INT Enumeration of the blind type.

Movement Types:

If set to -1 then a dealer can select a choice from a pulldown in the proxy property control.

Returns

None

Usage Note

This Notification sends DataToUI of: blind_setup xml.

STOPPED

State Notification used by the protocol to inform the proxy the blinds have stopped moving.  A Stop notification that uses the optional LEVEL parameter should be used if a blind is moving and changes direction.

Name

STOPPED ()

Parameter Type Description
LEVEL INT Where the blinds stopped at. This will also set the general level as well to this value.

Returns

None

Usage Note

This Notification Fires Director Event: Stop level_final is also updated to the value passed in through the level parameter. Sends DataToUI "Stopped" including: level - The level it stopped at.

MOVING

State Notification Used by the protocol to inform the proxy the blinds have started to move.

Name

MOVING ()

Parameter Type Description
LEVEL TARGET INT Integer of the target level that the blinds are currently expected to stop at.
RAMP RATE NUM Number of milliseconds it is expected to take to get to the level_target.
LEVEL INT Optional. Integer of the level the blind started moving from. If not specified, the proxy assumes the last level sent by a STOPPED Notification. This optional parameter should be sent in the case the blind was moving to a level but is interrupted/commanded to go to a different level.  Without specifying this parameter in an interruption case, Toggle on UIs and UI display of blind movement and direction will be inaccurate. Drivers might need to do a STOP or GET for hardware position before the blind direction is commanded to go to the new position in order to obtain an accurate LEVEL for this value of where the blind was before the new movement began.

Returns

None

Usage Note

This Notification Fires Director Event: Moving. Sends DataToUI: "Moving" including:

Blind Capabilities

always_send_level

If value is true, then the SetTargetLevel commands are always sent regardless of current level values. This is useful if the blind device does not support two-way communication and is controlled outside of the Control4 operating system. Setting this capability to True ensures that the SetTargetLevel values are always available so accurate blind performance can occur.

Signature

<always_send_level></always_send_level>

Parameter Description
bool True/False. Defaults to False

Example

<capabilities>
   <always_send_level>true</always_send_level>
</capabilities>

can_stop

Capability to stop movement of blinds

Signature

<can_stop></can_stop>

Parameter Description
bool True/False

Usage Note

This capability was delivered pre-2.9.0. It is still supported by the latest version of the proxy for drivers that do not have the has_level capbility defined.

Example

<capabilities>
   <can_stop>true</can_stop>
</capabilities>

driver_handles_toggle

Capability to stop movement of blinds

Signature

<driver_handles_toggle></driver_handles_toggle>

Parameter Description
bool True/False

Usage Note

This capability defaults to false. If false, the proxy will handle the toggle commands (which sends SET_LEVEL_TARGET commands to the driver) or if true will send a LEVEL_TOGGLE command to the driver so the driver can handle toggle as it desires.

We strongly recommend driver developers do not set this to true unless they absolutely must. Inconsistencies will occur if there are a mix of different driver types in a blind group. This will cause blinds to move differently when that group is commanded to toggle.  

The blind proxy has logic that treats toggle the same as lights in Control4.  If a blind is not moving but open any amount and someone presses toggle, the proxy will always send a SET_LEVEL_TARGET of the closed value.  This is due to the high possibility of someone entering a room and not knowing what direction the blind previously moved. However, if a blind is currently in motion and someone presses toggle, the proxy will send SET_LEVEL_TARGET of the opposite direction that the blind is moving. This has the most natural use of toggle for real-world scenarios.

Example

<capabilities>
   <driver_handles_toggle>true</driver_handles_toggle>
</capabilities>

has_level

A boolean capability indicating if the blind can support reporting of discrete level values through Notifications.  Default to False in order for older drivers to work.

Signature

<has_level></has_level>

Parameter Description
bool True/False

Usage Note

If stop is not supported 0 is closed and 1 is open.

If stop is supported 0 is closed and 1 is somewhere in the middle depending when stop is pressed and 2 for open.

If a blind supports closed, 4 distinct middle levels, and open then 0 is closed, 1-4 would be the distinct levels, and 5 would be open.

Reporting discrete values is possible even if accepting discrete commands is not. Presets, timers, or other formulas can be used to report discrete values.

Example

<capabilities>
    <has_level>true</has_level>
</capabilities>

level_closed

Integer indicating the closed level of the control surface. Default to 0. This capability is only needed if has_level is set and the value is other than 0. The value passed in this capability should be less than the value for level_open.

Signature

<level_closed></level_closed>

Example

<capabilities\>
    <level_closed>true</level_closed>
</capabilities>

level_open

Integer indicating the open level of the control surface. Defaults to 1 and must be a higher integer than level_closed. This capability is only needed if has_level is set and the value is other than 1.  For example, if the blind control supports adjustments every 5%, use 20.)

Signature

<level_open></level_open>

Example

<capabilities>
    <level_open>1</level_open>
</capabilities>

level_discrete_control

Boolean indicating if a control surface can be set by a COMMAND to something other than the level for closed and the level for open.

If false, a UI will only send level_closed and level_open integer values to the proxy/driver. However, a driver could still notify various levels interpolated based on movement and or duration/time in each direction or using another formula.

If true, the driver should support all level values in the level range. This could be discrete percentages or even include using level values of 1,2,3,... to execute presets. However, the min (0) and max (X) should always be programmed for close and open levels respectively.

Signature

<level_discrete_control</level_discrete_control>

Example

<capabilities>
    <level_discrete_control>true</level_discrete_control>
</capabilities>

level_closed_secondary

Integer indicating how far past open `(levelopen) the blind can go to a second closed state.   No default value exists for this capability and drivers should not include level_closed_secondary if a secondary closed position does not exist.

An example case is a full range louver with 11 positions (0% to 100% with 10% resolution) that has:

This gives the full close-open-close range of 0 to 10.  

It should be noted that a generic "Close" UI or Composer Programming commands will send the level_closed value for "Close".  No default value exists for this capability and drivers should not include level_closed_secondary if a secondary closed position does not exist.

Signature

<level_closed_secondary></level_closed_secondary>

Example

<capabilities>
    <level_closed_secondary>11</level_closed_secondary>
</capabilities>

level_unknown

Integer indicating the level value that is to be specified as "unknown blind position".  This is often, but not always, a value outside of the range of valid level values.  This allows a driver that is initializing (not yet communicating with the blind), lost communication or for any other reason does not know the exact location of the blind to notify Director that the current level is unknown.

Signature

<level_unknown></level_unknown>

Example

<capabilities\>
    <level_unknown>11</level_unknown>
</capabilities>

movement

Integer enumeration of a movement function for the blind.  If set in the driver, the pull-down to select this value will be disabled in the proxy. For louvers and other slate type objects, the movement observed is that of the forward/leading (aka nearest to the person viewing the movement) edge of the louver or slate.  

An example for a general louver would be where the primary closed position for the leading edge is Down, so Up (Middle) would be Open, and an optional Secondary Closed would be where the front edge is furthest up.

Signature

<movememt></movement>

Parameter Description
0 Open/Close (Open/Close)
1 Up to Down (Up is open, Down is closed)
2 Down to Up (Down is open, Up is Closed)
3 Out to In (Out is Open, In is Closed)
4 Left to Right (Left is Open, Right is Closed)
5 Right to Left (Right is Open, Left is Closed)

Example

<capabilities>
    <movememt>4</movememt>
</capabilities>

type

Integer representing the enumeration of a type of blind. If set in a driver, the pull-down to select this value will be disabled in the proxy

Signature

<type></type>

Parameter Description
0 Shade (Default as all coverings are considered to be Shades in the industry)
1 Group
2 Blind (Since a blind has slates/louvers that often move, a blind can be bound to a louver movement for association)
3 Louvre
4 Curtain
5 Shutter
6 Blackout
7 Opaque Glass
8 Awning
9 Door
10 Screen

Example

<capabilities>
    <type>6</type>
</capabilities>

Blind Events

The following Events are included with the 2.9.0 and later releases. The events fired by the proxy have to deal with changes in the blind itself. They include:

Open (ID=1) - Fired when the blinds are opened from a closed state.

Fully Closed (ID=2) - Fired when the blinds are fully closed from an open state.

Stopped (ID=3) - Fired when the stop notify arrives at proxy.

Fully Opened (4) - Fired when the blinds are at their full open state

Moving (ID=5) - Fired when the moving notify arrives at proxy.

Level_Changed (ID=6) - Fired when the level changes.

Level_Target_Changed (ID=7) - Fired when the level end changes.

Opening (ID=8) - Fired when the blinds begin to open

Closing (ID=9) - Fired when the blinds begin to close.

Blind Variables

Registered Variables included in post 2.9.0 releases include:

Open (ID=1000) - A boolean indicating if the control is open.  Will be true when level is at level_open.

Fully Closed (ID=1001) - A boolean indicating if the control is fully closed.  Will be true when level is at level_closed.

Stopped (ID=1002) - A boolean indicating if the blind is stopped.  On drivers that support stop and extended functionality, drivers must send stopped = false when the hardware starts to move and stopped = true once it has finished moving.

Fully Open (ID=1003) - A boolean indicating if the control is fully open.

Level (ID=1004) - An integer indicating the blind level (level range is potentially unique per driver.

Target Level (ID=1005) - An integer indicating the target blind level when the hardware is to stop.  This is used to know if a driver is currently going up or down.

Type (ID=1006) - A string representation of the enumeration for the type.

Movement (ID=1007) - A string representation of the enumeration for the movement.

Opening (ID= 1008) - A boolean indicating if the control is in the process of opening.

Closing (ID= 1009) - A boolean indicating if the control is in the process of closing.

lua