NAV Navbar
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 to 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 2022 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

Effective communication between your driver and Control4 System is paramount to a successful end user experience. The API Reference Guide details each of the Interfaces supported through the DriverWorksSDK. These Interfaces include numerous APIs that can be leveraged by your driver to facilitate communication between the driver and the Control4 O.S.

What's New

What’s New in 3.3.0

C4SSH Interface

The DriverWorks API has been expanded with the addition of the new C4SSH API. This API enables Lua drivers to establish an SSH client connection to a remote device and execute a series of commands. A driver creates an instance of a C4SSH object by calling the C4:CreateSSHClient function.

File Interface

As part of Control4’s plan to tighten driver security, the io.popen() call has bee removed. In doing this, driver developers need to use C4:File commands to accomplish what they previously did with io.popen (). The following APIs have been added or modified in support of this effort:

A new API: FileCreateDir has been added. This function has been added to create a new directory.

The FileDelete function has been modified in conjunction with O.S. release 3.3.0.

A new API: FileMove has been added. This function moves files within certain restrictions.

The FileSetDir has been modified In conjunction with O.S. release 3.3.0. This function is being restricted to allowed locations whereas previously it had full root access.

Additionally, a new API: UnZip has been added. This API enables Lua drivers to extract one, or more, files from a .zip archive.

Helper Interface

A new API: GetCodeItems has been added. This function returns Code Items for a specified device and event.

A new API: GetAllCodeItems has been added. This function returns all Code Items within the project.

A new API: GetBootID has been added. This function returns a string that contains an ID which is unique for the current kernel instance. When the controller is re-booted, the ID will change.

A new API: UUID has been added. This function generates a UUID (Universally Unique IDentifier). This function has also been added to tighten driver security and support the removal of the the io.popen() call.

Miscellaneous Interface

A new API: GetDriverFileName has been added. This function returns a string of the driver filename.

What’s New in 3.2.3

Timer Interface

A new API: GetTime has been added to the Timer Interface in this version of the SDK. This API enables Lua drivers to retrieve the number of milliseconds since the epoch.

What’s New in 3.2.2

Variable Interface

A new API: UnRegisterAllVariableListeners has been added to this version of the SDK.

What’s New in 3.2.1

Variable Interface

A new API: UnRegisteredAllVariableListeners has been added to this version of the SDK.

What’s New in 3.2.0

Driver Initialization and Destruction

New parameters have been added to OnDriverInit, OnDriverLateInit and OnDriver Destroyed. These parameters support instances when driver needs to know under what condition or event caused the Initialization or Destroyed functions to be called. OS Release 3.2.0 introduces a new string parameter for these functions to identify the reason for the call. This parameter, driverInitType (DIT) provides this information.

Driver Add Driver

Two new APIs have been delivered with O.S. 3.2.0 to facilitate the ability of driver to add another driver to a project as well as the ability to add a location within the project. See the AddDevice and AddLocation APIs for more information.

What was New in 3.1.0

New APIs that were Added

ToStringLocaleC - A new helper function which converts a number to a string using the ‘C’ locale regardless of the locale setting of the Control4 Operating System.

Interfaces that were Modified

Zigbee Interface

Future Changes to Zigbee Server-Side Cluster Management

Encryption Interface

A new Lua Signing API has been added to the SDK. C4:Sign enables drivers to crypto-graphically sign an arbitrary payload using a specified key. The API currently supports both HMAC & RSA signing. Control4 strongly recommends that driver developers implement this new API as soon as possible.

New Sample Drivers that were Added

A client side websocket driver has been added to the SDK to assist with websocket support. Sample drivers can be found in the Sample Driver folder at the root level of the SDK.zip.

What was New in O.S.3

New Interfaces that were Added

The Notification Interface allows device drivers to include .jpeg files within notifications. These images are displayed as part of the notification. The .jpeg file can be retrieved from a cloud service that supports the device, from the device itself or from a location on a Control4 Controller.

The Scheduler Agent Interface has been added which supports a driver's ability to create scheduled events that can be used in Programming in ComposerPro.

New APIs that were Added

The GetBindingsByDevice API returns all of the Binding information for a device. The GetNetworkBindingsByDevice API return all of the Network Binding information for a device. The GetNetworkConnections API returns connection information based on connection type. The GetProjectProperty API uses a single string parameter from a list of property names and returns the value of that property, if it exists.

Interfaces that were Modified

The Media Management Interface has been enhanced with content supporting Device Level Context and Broadcast Video APIs

The Timer Interface has been updated to identify legacy APIs that, while still valid, are not recommenced for new driver development. Additionally, a sample driver using the (recommended) SetTimer API has been included with the SDK.

The WebService Interface has been updated with a new sample driver that demonstrates how to perform basic C4:url calls.

Interfaces that were Modified

The AddVariable API has been enhanced with additional Parameter Types.

The JsonDecode API has been enhanced with a new optional parameter: decodeNull which indicates how null values are decoded. Additionally, c4json.null has been added. This can can be used to insert a null value into a JSON document or to test for a null value that was encountered in a JSON document.

The OnBindingChanged API has been updated to include missing parameters.

The PersistGetValue API has been updated with an option third parameter: encrypted.

The PersistSetValue API has been updated with an option third parameter: encrypted.

The RenameDevice API has updated content regarding passing a ProxyID or DeviceId value.

The UpdatePropertyList API has been modified with a parameter re-name and an additional, optional parameter.

APIs that were Deprecated

The Debug Interface content has been removed from the DriverWords SDK. The APIs that were defined in the Debug Interface were used in conjunction with an executable that supported remote debugging. Support for the debugging utility was discontinued several years ago. As a result, the following APIs have been removed:

C4SSH Interface

CreateSSHClient

The C4SSH API enables Lua drivers to establish an SSH client connection to a remote device and execute a series of commands. A driver creates an instance of a C4SSH object by calling the C4:CreateSSHClient function.

This interface was released in conjunction with O.S. 3.3.0

Signature

C4:CreateSShClient ()

Parameters

None

Returns

An instance of a C4SSH object that can be used to establish an SSH client connection to a remote device. The C4SSH object enables a Lua driver to establish an SSH client connection to a device, and then to interact with that device by executing a series of commands. The C4SSH object API provides the following methods:

These methods are defined below:

Connect

The Connect method attempts to establish a connection to a remote device. There are three methods that set callback functions which enable a driver to receive various notifications about the connection. These are:

SetOnConnected: Provides notification when a connection is established. SetOnData: Provides notification when data is read from the connection. SetOnDisconnected: Provides notification when the connection is disconnected, or has otherwise failed.

Additionally, a driver may control how long the C4SSH object waits before determining that the connection has failed. This is accomplished with: SetConnectTimeout which specifies the amount of time to wait when attempting to connect to an endpoint.

Signature

Connect(endpoint, username, password, string)

Parameters Description
Endpoint string. The endpoint to which the SSH connection is to be established. This can be either a host name or an IP address. If the caller specifies a host name, the C4SSH object will attempt to resolve the IP address of the endpoint before connecting.
Username string. The username with which to log in to the remote device.
Password string. The password to use when logging in to the remote device. This value can be empty if no password is required.
Port Integer. The port to use when establishing a connection to the remote device. If omitted, then the default port of 22 is used.

Returns

The Connect method may return multiple values. On success, Connect returns the following:

On failure, Connect returns the following:

See Also:

Send

Sends a command to a remote device. A driver may set a callback function to receive notification when data has been read from the connection by calling the SetOnData method.

Signature

Send(command)

Parameters Description
Command string. The command to be sent to the remote device.

Returns

The Send method may return multiple values. On success, Send returns the following:

On Failure, Send returns the following:

Usage Note

Due to the asynchronous nature of the C4SSH API, a driver must wait for a connection to be established before calling Send. A driver can be notified that a connection has been established successfully by calling SetOnConnected to register an OnConnected callback function.

See Also:

Disconnect

Closes the connection. A driver may set a callback function to receive notification when the connection has been disconnected by calling the SetOnDisconnected method.

Signature

Disconnect()

Parameters

None

Returns

The Disconnect method returns a single value which is the instance of the C4SSH object on which the Disconnect method was invoked.

Set Also

SetConnectTimeout

Sets the amount of time the C4SSH object waits before determining that an attempt to establish a connection to an endpoint has failed. The C4SSH object notifies a driver that a connection has timed out by invoking the OnDisconnected callback function. A driver may set the OnDisconnected callback function by calling SetOnDisconnected.

Signature

SetConnectTimeout(Timeout)

Parameters Description
Timeout integer.The number of seconds to wait before determining that an attempt to establish a connection has failed. The default is 30 seconds.

Returns

The SetConnectTimeout method may return multiple values. On Success, SetConnectTimeout returns the following:

On failure, SetConnectTimeout returns the following:

See Also

SetOnConnected

Sets the callback function that is invoked when a client connection has been established. See OnConnected for specific details about the function signature of this callback.

Signature

SetOnConnected(Callback)

Parameters Description
Callback function. A callback function to be invoked when a connection has been established.

Returns

The SetOnConnected method returns a single value which is the instance of the C4SSH object on which SetOnConnected was invoked.

See Also

SetOnData

Sets the callback function that is invoked when data has been read from a connection. See OnData for specific details about the function signature of this callback.

Signature

SetOnData(Callback)

Parameters Description
Callback function.A callback function to be invoked when data has been read from a connection.

Returns

The SetOnData method returns a single value which is the instance of the C4SSH object on which the SetOnData method was invoked.

See Also

SetOnDisconnected

Sets the callback function that is invoked when a connection is disconnected or has otherwise failed. Note that the C4SSH object invokes the OnDisconnected callback to notify a driver when an error has forced the closure of a connection. See OnDisconnected for specific details about the function signature of this callback.

Signature

SetOnDisconnected(Callback)

Parameters Description
Callback function. A callback function to be invoked when a connection is disconnected or has otherwise failed.

Returns

The SetOnDisconnected method returns a single value which is the instance of the C4SSH object on which SetOnDisconnected was invoked.

See Also

C4SSH Callbacks

The C4SSH object provides the following callback functions that enable a driver to receive various notifications about the connection. These include the following:

OnConnected

The OnConnected callback is invoked to notify a driver that a connection has been established.

Signature

OnConnected(client)

Parameters

Parameters Description
client [C4SSH]: The instance of the C4SSH object that connected successfully.

See Also

Example

function OnData(client, data)
    print(client, "OnData")
    print(data)
    client:Disconnect()
end

function OnConnected(client)
    print(client, "OnConnected")
    client:Send("ls")
end

function OnDisconnected(client, error)
    print(client, "OnDisconnected", error)
end

sshclient = C4:CreateSSHClient()

sshclient:SetOnDisconnected(OnDisconnected)
sshclient:SetOnConnected(OnConnected)
sshclient:SetOnData(OnData)

sshclient:Connect("192.168.1.42", "username", "password")

OnData

The OnData callback is invoked to notify a driver when data has been read from a connection.

Signature

OnData(Client, Data)

Parameters Description
client [C4SSH]: The instance of the C4SSH object that received the data.
Data string. A string containing the data that was read from the connection.

See Also

Example

function OnData(client, data)
    print(client, "OnData")
    print(data)
    client:Disconnect()
end

function OnConnected(client)
    print(client, "OnConnected")
    client:Send("ls")
end

function OnDisconnected(client, error)
    print(client, "OnDisconnected", error)
end

sshclient = C4:CreateSSHClient()

sshclient:SetOnDisconnected(OnDisconnected)
sshclient:SetOnConnected(OnConnected)
sshclient:SetOnData(OnData)

sshclient:Connect("192.168.1.42", "username", "password")

OnDisconnected

The OnDisconnected callback is invoked to notify a driver that a connection has been disconnected. If an error forced the closure of the connection, then the Error argument provides a string describing the error.

Signature

OnDisconnected(client Error)

Parameters Description
client [C4SSH]: The instance of the C4SSH object that was disconnected.
Error string. A string describing the failure if an error forced the closure of the connection. If no error occurred, then the value of the Error argument is nil.

See Also

Example

function OnData(client, data)
    print(client, "OnData")
    print(data)
    client:Disconnect()
end

function OnConnected(client) print(client, "OnConnected") client:Send("ls") end

function OnDisconnected(client, error) print(client, "OnDisconnected", error) end

sshclient = C4:CreateSSHClient()

sshclient:SetOnDisconnected(OnDisconnected) sshclient:SetOnConnected(OnConnected) sshclient:SetOnData(OnData)

sshclient:Connect("192.168.1.42", "username", "password")

Controller Registry Interface

RegistryDeleteValue

Removes a key/value pair from the Registry.

Available from 2.10.4

Signature

C4:RegistryDeleteValue(key)

Parameter Description
num The key to be removed from the Registry

Returns

None

RegistryGetValue

Retrieves a value from the Registry.

Available from 2.10.4

Signature

C4:RegistryGetValue(key)' |Parameters | Description| | --- | --- | | num | The key applicable to the value being retrieved. |

Returns

Upon success, the API returns the value that was decoded from the Registry. The value can be any of the following: number, string ,boolean, table. Upon failure, the API returns nil.

RegistrySetValue

Sets the value of a Registry key/value pair. The value is updated if the specified key/value pair exists. A key/value pair is created by the API if it does not exist.

Available from 2.10.4

Signature

C4:RegistrySetValue(key, value)

Parameters Description
num The name of the key to which the specified value is associated.
value The value of the key to which the specified value is associated.

Returns

Upon success, the API returns the value that was decoded from the Registry. The value can be any of the following: number, string ,boolean, table. Upon failure, the API returns nil.

Director Command Interface

ExecuteCommand

Function called by Director when a command is received for this DriverWorks driver. This includes commands created in Composer programming. This API should not be invoked during OnDriverInit.

Available in 1.6.0.

Signature

ExecuteCommand(strCommand, tParams)

Parameter Description
str Command to be sent
table Lua table of parameters for the sent command

Returns

None

Usage Note

Prior to Operating System 2.10, overuse of C4:InvalidateState()was an issue as persisting extraneous data through a driver had performance implications. Beginning with Operating System 2.10, it is no longer necessary to cause driver data to be persisted. Drivers should use the PersistSetValue and PersistGetValue functions to store data that will be required across system restarts.

Examples:

Print all commands received for this protocol driver, including all parameters:

function ExecuteCommand (strCommand, tParams)
 print("ExecuteCommand: " .. strCommand)
 if (tParams \~= nil) then
   for ParamName, ParamValue in pairs(tParams) do 
     print(ParamName, ParamValue) 
   end
 end
end

This sample function evaluates the commands received from Director and calls the correct function. It also looks for LUA_ACTION commands, which are sent from Composer’s Actions tab and processes them:

function ExecuteCommand(strCommand, tParams)
print("ExecuteCommand function called with : " .. strCommand)
  if (tParams == nil) then
    if (strCommand =="GET\_PROPERTIES") then
      GET\_PROPERTIES()
    else
      print ("From ExecuteCommand Function - Unutilized command: " .. strCommand)
    end
  end
  if (strCommand == "LUA\_ACTION") then
    if tParams \~= nil then
      for cmd,cmdv in pairs(tParams) do 
        print (cmd,cmdv)
        if cmd == "ACTION" then
          if cmdv == "Reset Security System" then
            ResetSecuritySystem()
          else
            print("From ExecuteCommand Function - Undefined Action")
            print("Key: " .. cmd .. "  Value: " .. cmdv)
          end
        else
          print("From ExecuteCommand Function - Undefined Command")
          print("Key: " .. cmd .. "  Value: " .. cmdv)
        end
      end
    end
  end
end

GetVersionInfo

Function that returns the version of Director that is currently running. This API can be invoked during OnDriverInit.

Available in 1.60.

Signature

C4:GetVersionInfo()

Parameters

None

Returns

Value Description
buildtime HH:MM:SS
builddate mm dd yyyy
version 1.7.0.222
buildtype DEBUG

Example


local tVers = C4:GetVersionInfo()
local strVers = tVers["version"]

local major, minor, rev, build = string.match(strVers, "(%d+).(%d+).(%d+).(%d+)")

print("Major: " .. major .. " Minor: " .. minor .. " Rev: " .. rev .. " Build: " .. build)

if (tonumber(major) < 2) then if (tonumber(minor) < 8) then print("This Code requires at least version 1.8 to operate properly. You are currently running version " .. strVers) end end GetVersionInfo

InvalidateState

Function to notify director that data from this driver has been modified and needs to be persisted. This API should not be invoked during OnDriverInit.

Signature

C4:InvalidateState()

Usage Note

Prior to Operating System 2.10, overuse of C4:InvalidateState() was an issue as persisting extraneous data through a driver had performance implications. Beginning with Operating System 2.10, it is no longer necessary to cause driver data to be persisted. Drivers should use the PersistSetValue and PersistGetValue functions to store data that will be required across system restarts.

Encryption Interface

Encode

local data = 'Hello World This Is London Calling'
local data_encoding = 'BASE64'
local encoded_data, err = C4:Encode (data, data_encoding)
print (type (encoded_data), encoded_data)

Output:

string  SGVsbG8gd29ybGQ=

Encodes a given string with the specified data encoding.

Available in 1.6.0.

Signature

C4:Encode (data, data_encoding)

Parameter Description
str data Data to encode.
str data_encoding: 'NONE' / ‘HEX' / ‘BASE64'

Returns

result, err

A successful operation will return nil for err. If an error occurs, then result will be nil and err will contain the description of the error.

Value Description
str result: Encoded data
str err: Description of any error that occurred

Encrypt

local cipher = 'AES-256-CBC'
local key = 'Super Secret Key'
local iv = 'IV For C4'
local data = 'Hello World, this is London calling'
local options = {
    return_encoding = 'BASE64',
    key_encoding = 'NONE',
    iv_encoding = 'NONE',
    data_encoding = 'NONE',
    padding = true,
}
local encrypted_data, err = C4:Encrypt (cipher, key, iv, data, options)
print (type (encrypted_data), encrypted_data)

Output:

string  HMQ9QXyBFUBnTAXBl2zi6k6abipQYQjpc37B0nA3WaxK9vBNrqKKAEzIglxWkA46

Encrypts a given string with the specified cipher, using the specified key and IV.

Available in 1.6.0.

Signature

C4:Encrypt (cipher, key, iv, data, options)

Parameter Description
str cipher: Valid cipher (see GetSupportedCiphers).
str key : Valid key for specified cipher. Short keys will be padded, long keys will be rejected.
str iv: Valid IV for specified cipher. Short IVs will be padded (including empty/nil IVs), long IVs will be rejected
str data: Data to encrypt.
table Options: (Optional) Options to specify encoding of inputs and outputs

Valid key/value pairs for options parameter:

Key Description
str return_encoding: return_encoding: 'NONE' / 'HEX' / 'BASE64'
str key_encoding: 'NONE' / 'HEX' / 'BASE64'
str iv_encoding : 'NONE' / 'HEX' / 'BASE64’
str data_encoding: 'NONE' / 'HEX' / 'BASE64'
bool padding: True. Controls the padding requirements for the cipher used

Returns

result, err

A successful operation will return nil for err. If an error occurs, then result will be nil and err will contain the description of the error.

Value Description
str result: Encrypted data
str err : Description of any error that occurred

Decode

local data = 'SGVsbG8gd29ybGQ='
local data_encoding = 'BASE64'
local decoded_data, err = C4:Decode (data, data_encoding)
print (type (decoded_data), decoded_data)

Output:

string  Hello World

Decodes a given string that was previously encoded with the specified data encoding.

Available in 1.6.0.

Signature

C4:Decode (data, data_encoding)

Parameter Description
str Data to decode
str data_encoding: string: 'NONE' / 'HEX' / 'BASE64’

Returns

result, err

A successful operation will return nil for err. If an error occurs, then result will be nil and err will contain the description of the error.

Value Description
str result: Decoded data
str err: Description of any error that occurred

Decrypt

local cipher = 'AES-256-CBC'
local key = 'Super Secret Key'
local iv = 'IV For C4'
local data = 'HMQ9QXyBFUBnTAXBl2zi6k6abipQYQjpc37B0nA3WaxK9vBNrqKKAEzIglxWkA46'
local options = {
    return_encoding = 'NONE',
    key_encoding = 'NONE',
    iv_encoding = 'NONE',
    data_encoding = 'BASE64',
    padding = true,
}
local decrypted_data, err = C4:Decrypt (cipher, key, iv, data, options)
print (type (decrypted_data), decrypted_data)

Output:

string  Hello World, this is London calling

Encrypts a given string with the specified cipher, using the specified key and IV.

Available in 1.6.0.

Signature

C4:Decrypt (cipher, key, iv, data, options)

Parameter Description
str Valid cipher (see GetSupportedCiphers).
str Valid key for specified cipher. Short keys will be padded, long keys will be rejected.
str Valid IV for specified cipher. Short IVs will be padded (including empty/nil IVs), long IVs will be rejected
str Data to decrypt.
table Optional. Options to specify encoding of inputs and outputs:

Valid key/value pairs for options parameter:

Key Description
str return_encoding: 'NONE' / 'HEX' / 'BASE64'
str key_encoding: 'NONE' / 'HEX' / 'BASE64'
str iv_encoding
str data_encoding: 'NONE' / 'HEX' / 'BASE64'
bool padding: true Controls the padding requirements for the cipher used

Returns

result, err

A successful operation will return nil for err. If an error occurs, then result will be nil and err will contain the description of the error.

Value Description
str Decrypted data
str err: Description of any error that occurred

GenerateCSR ECC

This API will generate a certificate signing request (CSR) which, when sent to a certificate authority, will return a digital identity certificate that meets the encryption criteria defined by Elliptic-curve cryptography (ECC) standard. The use of this API assumes a thorough knowledge of public-key cryptosystems and the ECC cryptosystem definition.

Available in 3.1.2.

Signature

C4:GenerateCSP_ECC(digest, curve, subject, tx509_exts) 

Parameter Description
digest The algorithm used by the certificate. For example, SHA256. See the C4:GetSupportedDigests()API for information on retrieving digests.
curve The elliptical curve encoding format for the certificate.
subject The person, organization or device required by the certificate. For example: "/C=US/ST=Utah/L=SLC/O=Foo/OU=Controller Certificates/CN=foo.bar.com
tx509_exts Optional table of key/value pairs. Used in the event that the desired certificate contains X.509 encryption data.

Returns

None

Examples

Generate a CSR using ECC requirements:

local csr = C4:GenerateCSR_ECC("SHA256", "secp256k1", "/C=US/ST=Utah/L=Draper/O=Control4/OU=Controller Certificates/CN=foo.bar.com")

The resulting CSR to the right is generated:

 -----BEGIN CERTIFICATE REQUEST-----
MIIB0TCCAXcCAQAweDELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFV0YWgxDzANBgNV
`BAcMBkRyYXBlcjERMA8GA1UECgwIQ29udHJvbDQxIDAeBgNVBAsMF0NvbnRyb2xs`
`ZXIgQ2VydGlmaWNhdGVzMRQwEgYDVQQDDAtmb28uYmFyLmNvbTCB9TCBrgYHKoZI`
zj0CATCBogIBATAsBgcqhkjOPQEBAiEA////////////////////////////////
/////v///C8wBgQBAAQBBwRBBHm+Zn753LusVaBilc6HCwcCm/zbLc4o2VnygVsW
`+BeYSDradyajxGVdpPv8DhEIqP0XtEimhVQZnEfQj/sQ1LgCIQD/////////////`
`///////+uq7c5q9IoDu/0l6M0DZBQQIBAQNCAAQXXbHNU5r5vYzZRYhPZGKFcSBe`
I+D0y0pvyw+tUo8eGO9QjHqmw6A0vm5OyRR3C9qDH8msuDO1ZgieUkCfnfYSoAAw
CgYIKoZIzj0EAwIDSAAwRQIgMvJKuHT2E+um/iXdUNhJK61jSI1ygcjR77lCZM2E
`aRkCIQCcZLJvubYxdGxB0q7ApSBujF/L6/UtL/gjuolLE6JUaw==`
  -----END CERTIFICATE REQUEST----- 

Generate a CSR using ECC requirements with the optional X.509 parameter:

local csr = C4:GenerateCSR_ECC("SHA256", "secp256k1", "/C=US/ST=Utah/L=Draper/O=Control4/OU=Controller Certificates/CN=foo.bar.com", {subjectKeyIdentifier = "hash", subjectAltName = "DNS:acs.qacafe.com, DNS:www.acs.qacafe.com"})

The resulting CSR is generated:

--- X.509 Example

-----BEGIN CERTIFICATE REQUEST-----
MIICIzCCAcgCAQAweDELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFV0YWgxDzANBgNV`
BAcMBkRyYXBlcjERMA8GA1UECgwIQ29udHJvbDQxIDAeBgNVBAsMF0NvbnRyb2xs
ZXIgQ2VydGlmaWNhdGVzMRQwEgYDVQQDDAtmb28uYmFyLmNvbTCB9TCBrgYHKoZI`
zj0CATCBogIBATAsBgcqhkjOPQEBAiEA////////////////////////////////
/////v///C8wBgQBAAQBBwRBBHm+Zn753LusVaBilc6HCwcCm/zbLc4o2VnygVsW
+BeYSDradyajxGVdpPv8DhEIqP0XtEimhVQZnEfQj/sQ1LgCIQD/////////////
///////+uq7c5q9IoDu/0l6M0DZBQQIBAQNCAASu8/6lwqmnPbMLCvXIIU38ZmAo
LjjaMLNhzAgAnWYz/lzg3h8FXcuC/W6jv83inkfgu/4Zutp/GxAQLBqA+lkeoFEw
TwYJKoZIhvcNAQkOMUIwQDALBgNVHQ4EBGhhc2gwMQYDVR0RBCpETlM6YWNzLnFh
Y2FmZS5jb20sIEROUzp3d3cuYWNzLnFhY2FmZS5jb20wCgYIKoZIzj0EAwIDSQAw
RgIhAI78Y9z3cIlRinJVmyx7I+7uA37HEfofzdSktra4Lm5nAiEAxTep97UadRb1
phLqvILbPqe2Lsm8JyCg/yEn5JlfncA=
 -----END CERTIFICATE REQUEST-----

GenerateCSR RSA

This API will generate a certificate signing request (CSR) which, when sent to a certificate authority, will return a digital identity certificate that meets the encryption criteria defined by the Rivest–Shamir–Adleman (RSA) standard. The use of this API assumes a thorough knowledge of public-key cryptosystems and the RSA cryptosystem definition.

Available in 3.1.2.

Signature

C4:GenerateCSP_RSA(digest, sizeCert, subject, tx509_exts)

Parameter Description
digest The algorithm used by the certificate. For example, SHA256. See the C4:GetSupportedDigests()API for information on retrieving digests.
sizeCert The Key size of the certificate. For example, 2048.
subject The person, organization or device required by the certificate.
tx509_exts Optional table of key/value pairs. Used in the event that the desired certificate contains X.509 encryption data.

Returns

None

Examples

Generate a CSR using RSA requirements:

local csr = C4:GenerateCSR_RSA("SHA256", 2048, "/C=US/ST=Utah/L=Draper/O=Control4/OU=Controller Certificates/CN=foo.bar.com")

The resulting CSR to the right is generated:

BEGIN CERTIFICATE REQUEST-----
MIICvTCCAaUCAQAweDELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFV0YWgxDzANBgNV
BAcMBkRyYXBlcjERMA8GA1UECgwIQ29udHJvbDQxIDAeBgNVBAsMF0NvbnRyb2x~~s
ZXIgQ2VydGlmaWNhdGVzMRQwEgYDVQQDDAtmb28uYmFyLmNvbTCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBALzSLHvRT8QcVbfFlxCCUkGEL2irn8r6DxBM
+XEK6/xXeAVZ/oWRAiGOHBNeqmdaUz0ib4ANdTHn8jEUB2t38cDVEJ88o4BiE+/D
rpmUphIKXh3Hp57PwyC0EKHQ2POq6e75AxOMouCdtbbLgBDxmD6WWM6ojEwphEQ2
M6JM6ZJA9pDQ/UanbGWruvKFEm9AUdo+hAjoFgObDqhWLLIwXFeSyz6y/0aymBam
jtO/ovOS/5moNy+ENBeOsLC2ayCn4Fquj77Y825Ye9kYPkiVkkcEtawAEEFebZJY
pUE8SwBOYjjHYJoWFDv+vcxWBFlc0ECTFKeB9Bd4vi2TF+IlwpsCAwEAAaAAMA0G
CSqGSIb3DQEBCwUAA4IBAQBv4Z7e1cD1gbNy0PXYyugQpbG19umTcZkQN+BlK5TY
+VcNLKK/56IPaxX7ZeHpe3DQPOXnTmc/+wVremZ6h7TwSxUOBFY9DjVUuh0thWsB
t+xUzWt4Oae0ymP8JF83b9RZl1EGGsAsQopB+Uu4P9VgwjHm9PTXVBheofbZ/yXp
oeom+w0fl+/qCcIjvDAGh8ODz4gfk6Mjl1iiQykOyWeGhZiGyd6G80IAF1pjciVS
O94cvy6o9EAAgujSCmCZFOgx3kwOfLZ/r1rq5jRvyyjK7wzL7bZHHjBJBLpe/tx0
AV+GeKVQe0nHme1tt1n+ZC5mIZ0q7qjKL3wwl4ckwTg/
      -----END CERTIFICATE REQUEST—

Generate a CSR using RSA requirements with the optional X.509 parameter:

local csr = C4:GenerateCSR_RSA("SHA256", 1024, "/C=US/ST=Utah/L=Draper/O=Control4/OU=Controller Certificates/CN=foo.bar.com", {subjectKeyIdentifier = "hash", subjectAltName = "DNS:acs.qacafe.com, DNS:www.acs.qacafe.com"})

The resulting CSR to the right is generated:

 X.509 Example

 -----BEGIN CERTIFICATE REQUEST-----
MIICCTCCAXICAQAweDELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFV0YWgxDzANBgNV
BZXIgQ2VydGlmaWNhdGVzMRQwEgYDVQQDDAtmb28uYmFyLmNvbTCBnzANBgkqhkiG
9w0BAQEFAAOBjQAwgYkCgYEA3djqm4PIBftyev9W0W4U+2XlwKHepq2o+dWPSk5s
/UzNd0TCeYoM02r+sTzQN2lkiGMYoPoKvP6qvQFWBzprtkS40z11S8AYGLqwKvxy
/MC8YcWjgGgvZB0h51TdW1OFdFT+yL68jnO9rGGIlfHx5DMyYypZf3tJKLczLVrh
rY0CAwEAAaBRME8GCSqGSIb3DQEJDjFCMEAwCwYDVR0OBARoYXNoMDEGA1UdEQQq
RE5TOmFjcy5xYWNhZmUuY29tLCBETlM6d3d3LmFjcy5xYWNhZmUuY29tMA0GCSqG
SIb3DQEBCwUAA4GBAA8Rz0fl6ue23HBENNV151uF0mQ9aT6/Z5S+8w8XTXXmf76B
OtTWXwPsxfsfxtZgRyKIGS4evUFN9jQIyEJNDj1+gvN2YFcm7bZFnPgq1m2vA3R1
TI9W6D463RicdNwjO92RYUgSm58Q1tCpyvlQqnedzvihQw1JFRgcIGNhbqI5
 -----END CERTIFICATE REQUEST-----

GetSupportedCiphers

Returns the list of ciphers supported by the Encrypt and Decrypt functions.

Available in 1.6.0.

Signature

C4:GetSupportedCiphers ()

Returns

ciphers

Value Description
table ciphers: Table of supported ciphers. Each element is a key/value pair, where the key is the cipher name and the value is the list of parameters for that cipher.

Valid key/value pairs for ciphers element value:

Value Description
num BlockSize: The size (in bytes) of each block for this cipher
num KeyLength: The maximum size (in bytes) of the key for this cipher (shorter keys will be padded)
num IVLength: The maximum size (in bytes) of the IV for this cipher (shorter IVs will be padded)

Example

local supportedCiphers = C4:GetSupportedCiphers ()
for k,v in pairs (supportedCiphers ['AES-256-CBC']) do
    print (k, v)
end

> Output:

BlockSize   16
KeyLength   32
IVLength    16

GetSupportedDigests

Returns the list of digests supported by the Hash, HMAC and PBKDF2 functions.

Available in 1.6.0.

Signature

C4:GetSupportedDigests ()

Returns

Value Description
table digests: Table of supported digests. Each element is a key/value pair, where the key is the digest name and the value is the list of parameters for that digest.

Valid key/value pairs for digest element value:

Value Description
num Size: The size (in bytes) of the output of this digest

Example

local supportedDigests = C4:GetSupportedDigests ()
for k,v in pairs (supportedDigests ['SHA256']) do
    print (k, v)
end

> Output:

Size    32

Hash

Hashes a given string with the specified digest.

Available in 1.6.0.

Signature

C4:Hash (digest, data, options)

Parameter Description
str digest: Valid digest (see GetSupportedDigests).
str data: Data to hash.
table options: (Optional) Options to specify encoding of inputs and outputs:

Valid key/value pairs for options parameter:

Key Description
str return encoding: 'NONE' / 'HEX' / 'BASE64'
str data encoding: 'NONE' / 'HEX' / 'BASE64'

Returns

A successful operation will return nil for err. If an error occurs, then result will be nil and err will contain the description of the error.

Value Description
str result: Encrypted data
str err : Description of any error that occurred

Example

local digest = 'SHA256'
local data = 'Hello World, this is London calling'
local options = {
    return_encoding = 'HEX',
    data_encoding = 'NONE',
}
local digest_output, err = C4:Hash (digest, data, options)
print (type (digest_output), digest_output)

> Output:

string  3fa83003c1c41282cac40d71b680d85f981f1517e5ac4941bd871955aeecbfec

HMAC

Computes a hash-based message authentication code (HMAC) for a given string using the specified key.

Available in 1.6.0.

Signature

C4:HMAC (digest, key, data, options)

Parameter Description
str digest: Valid digest (see GetSupportedDigests).
str key: Key to use for computing HMAC.
str data: Data to compute HMAC for.
table options: (Optional) Options to specify encoding of inputs and outputs:

Valid key/value pairs for options parameter:

Key Description
str return_encoding: 'NONE' / 'HEX' / 'BASE64'
str ey_encoding: ‘NONE' / 'HEX' / 'BASE64'
str data_encoding’: ‘NONE' / 'HEX' / 'BASE64'

Returns

A successful operation will return nil for err. If an error occurs, then result will be nil and err will contain the description of the error.

Value Description
str result: Computed HMAC value
str err: Description of any error that occurred

Example

local digest = 'SHA256'
local key = 'Super Secret Key'
local data = 'Hello World, this is London calling'
local options = {
    return_encoding = 'HEX',
    key_encoding = 'NONE',
    data_encoding = 'NONE',
}
local hmac_output, err = C4:HMAC (digest, key, data, options)
print (type (hmac_output), hmac_output)

> Output:

string  6402b5430d06db90c84e91a3ed605ba12964ff29e7bbd197b54109ac72aa58ce

LoadPKCS12

Load a certificate and private key from a #PKCS12 file.

The Lua PKCS #12 interface enables drivers to manage certificates and private keys using the PKCS #12 file format. These files are encrypted and protected by a password. This ensures that cryptographic assets are secure and are not easily recovered.

Available in 3.1.2.

Signature

C4:LoadPKCS12(filename, password) 

Parameter Description
str Path to the #PKCS12 file to load
str The password for unlocking the file.

Returns

Success returns multiple values consisting of: true, string, string.

Value Description
true Indicates that the load operation was successful.
string The PEM-encoded certificate.
string The PEM-encoded private key.

Failure returns multiple values consisting of: false, string

Value Description
false Indicates that the load operation failed
str A description of the error that occurred

Example

local filename = "Foo.p12"
local password = "PaSsWoRd"

result, cert, key = C4:LoadPKCS12(filename, password)
   if (result) then
   print("Success!")
 else
   print("Something horrible has happened: ", cert)
end

PBKDF2

Performs a Password-Based Key Derivation Function 2 (PKCS#5) (PBKDF2) for a given password using the specified digest, salt, number of iterations and desired output key length.

Available in 1.6.0.

Signature

C4:PBKDF2 (digest, password, salt, iterations, key_length, options)

Parameter Description
str digest: Valid digest (see GetSupportedDigests).
str password: Input password to generate PBKDF2 output for
str salt: Cryptographic salt to use
num iterations: Number of iterations to run
num key_length: Number of bytes to generate as output
table options: (Optional) Options to specify encoding of inputs and outputs:

Valid key/value pairs for options parameter:

Key Description
str return_encoding: 'NONE' / 'HEX' / 'BASE64'
str salt_encoding: ‘NONE' / 'HEX' / 'BASE64'

Returns

result, err

A successful operation will return nil for err. If an error occurs, then result will be nil and err will contain the description of the error.

Value Description
str result: Computed HMAC value
str err : Description of any error that occurred

Example

local digest = 'SHA256'
local password = 'My Voice Is My Passport'
local salt = 'NaCl is one of many'
local iterations = 100000
local keyLen = 32
local options = {
    return_encoding = 'HEX',
    salt_encoding = 'NONE',
}
local pbkdf2_output, err = C4:PBKDF2 (digest, password, salt, iterations, keyLen, options)
print (type (pbkdf2_output), pbkdf2_output)

> Output:

string  12675672222506b342f05c0406f43e2af944bcb4ba592bf45e1c7cebad0fcdee

Sign

Sign enables drivers to crypto-graphically sign an arbitrary payload using a specified key.  The API currently supports both HMAC & RSA signing. Control4 strongly recommends that driver developers implement this new API beginning with OS Release 3.1.0. This API is the best solution to cryptographically sign a payload. Control4 recommends its use rather than other Lua libraries.

Available in 3.1.0.

Signature

C4:Sign(operation, digest, key, data, [options])

Parameter Description
str Specifies which signing operation to perform. Valid values are: HMAC: Use the HMAC (hash-based message authentication code) signing algorithm. RSA: Use the RSA (Rivest-Shamir-Adleman) signing algorithm.
str Identifies which digest to use when signing. This can be one of the following values: HMAC: Any supported hashing digest can be used. RSA: Must be one of SHA1, SHA224, SHA256, SHA384, SHA512, MD5, MD5_SHA1, MD2, MD4, MDC2, or RIPEMD160.
key The key to use for signing. The key_encoding option identifies the format of the key (see options below). HMAC: The key can be of any length, but cannot be empty. Control4 recommends that the size of the key be the same as the digest. For example, a 256-bit key for SHA256 or a 160-bit key for RIPEMD160. RSA: The key must be an RSA key that is valid for signing. Note that RSA public keys are typically not valid for signing.
data The data to be signed. The data_encoding option identifies the format of the data (see options below).

Options:

key_encoding

Identifies the format of the key. Valid values for this option are:

data_encoding

Identifies the format of the data. Valid values for this option are:

return_encoding

Identifies the format of the result (signature). Valid values for this option are:

Returns

Success: Returns a string containing the signature.

Failure: Returns the following multiple results:

Value Description
nil A value of nil indicates that an error occurred.
str A string containing a description of the error.

Examples

options = {}
options["key_encoding"] = "PEM"
options["return_encoding"] = "BASE64"
key = [[-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQC8cDObD4DjL3TnUR7JxObq+pwb4XX6UYjXuM1zzl/4gvQ8KzA4
CDl8S5FQeaPe4vdrLHEJudxSJc7JWehMwcS+jP6xO1pRA68SBphq9I5G/itBw5zx
RSGi26NDTiu7XczTRTPGRyBRNxBiln4hWg3ordY5gn0PYe30Fem9vTyZ1QIDAQAB
AoGAPTNfv1uwq5iNKleRXUyjBuwv6Wo3a/4xKIbvy03ao5a8hhIszfX13aWZY36u
N0SVwOwlJliD8vYui/y0UsGYCRCKrBFh5iBlL4bd4bOg/3uD9EXqiZQiT/BeYAD5
TYozqtsBU8DhZytdX3OcmLlKwhX+fzKMC2/UWPkEQ2TlSX0CQQDd/DgdI6WbCn3f
sIJo6yEA98ZivayuoePfRP8CHaIAOVO6KOa1wYwR/nmrUmPSFZDUpvwB7mvel4WN
3VqNO9sXAkEA2VAKopLmgdL+KNZdpg2BB3eVMMDefhXC04tBmUpWX6qaFEVsw+gl
DYnDel3gv43iq3xqszaKEJy+1T+bR9tV8wJAc4ecvK2ctsATGqQGewxENPi/KwyE
Hq7qpXyHK1a4xV0QkkZPLDD68TJ7qApNIT1QDxyI84heY46AV4Doa7DHKQJBAMj0
l6EXL0nGj3m8IgW4XyVElBXthNIb1XpCQHs8nvsAjFNKj/Xp6rnGN5okzfzVfFMQ
TqtDOBF8oYwZscKVNbkCQFolrfE1I7DMTuQNHmF6kMXr/0gjhDTbUOOP3kzCSK14
iSpRAwom9R5BWUMFoRCn0j0TWFsTIBNSuOcMrw5n6NU=
-----END RSA PRIVATE KEY-----]]
signature=C4:Sign("RSA", "SHA256", key, "Walla Walla Washington", options)
print(signature)


options = {}
options["key_encoding"] = "BASE64"
options["return_encoding"] = "HEX"
key = "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2cu"
signature = C4:Sign("HMAC", "SHA256", key, "Walla Walla Washington", options)
print(signature)


options = {}
options["key_encoding"] = "BASE64"
options["return_encoding"] = "HEX"
key = "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2cu"
signature = C4:Sign("HMAC", "SHA256", key, "Walla Walla Washington", options)
print(signature)

WritePKCS12

Writes a certificate and private key to a specified #PKCS12 file.

The Lua PKCS #12 interface enables drivers to manage certificates and private keys using the PKCS #12 file format. These files are encrypted and protected by a password. This ensures that cryptographic assets are secure and are not easily recovered.

Available in 3.1.2.

Signature

C4:WritePKCS12(filename, password, certificate, key, label, options)

Parameter Description
str Path to the #PKCS12 file that will be created
str The password for securing the file.
str The PEM-encoded certificate to be stored in the file.
key The PEM-encoded private key to be stored in the file.
str An optional string containing the label, or "friendly name".

Returns

Success returns true.

Failure: Returns multiple values consisting of false and string.

Value Description
false Indicates that the write operation failed
string A description of the error that occurred.

Example

local filename = "Foo.p12"
local password = "PaSsWoRd"
local label = "This is my excellent certificate"

local certificate = [[` -----BEGIN CERTIFICATE----- MIIDLTCCAhUCCQC5eca/KJpLETANBgkqhkiG9w0BAQsFADCBkTEVMBMGA1UEAwwM Y29udHJvbDQuY29tMQ0wCwYDVQQIDARVdGFoMQswCQYDVQQGEwJVUzEdMBsGA1UE CgwUQ29udHJvbDQgQ29ycG9yYXRpb24xFDASBgNVBAsMC0VuZ2luZWVyaW5nMScw JQYJKoZIhvcNAQkBFhhlbmdpbmVlcmluZ0Bjb250cm9sNC5jb20wHhcNMTQwNzA3 MjEzMTA4WhcNNDExMTIyMjEzMTA4WjCBojELMAkGA1UEBhMCVVMxDTALBgNVBAgM BFV0YWgxDzANBgNVBAcMBkRyYXBlcjEdMBsGA1UECgwUQ29udHJvbDQgQ29ycG9y YXRpb24xFDASBgNVBAsMC0VuZ2luZWVyaW5nMRUwEwYDVQQDDAxjb250cm9sNC5j b20xJzAlBgkqhkiG9w0BCQEWGGVuZ2luZWVyaW5nQGNvbnRyb2w0LmNvbTCBnzAN BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvHAzmw+A4y9051EeycTm6vqcG+F1+lGI 17jNc85f+IL0PCswOAg5fEuRUHmj3uL3ayxxCbncUiXOyVnoTMHEvoz+sTtaUQOv EgaYavSORv4rQcOc8UUhotujQ04ru13M00UzxkcgUTcQYpZ+IVoN6K3WOYJ9D2Ht 9BXpvb08mdUCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAmMloM/SyJoC4JwZx6o3p NfRBmtXZNK7GaHUe49d1o68IGzwhEg9lOYC9oD6krRonN80AczSW0igN/gHxYtti 1Rf/YhYH/GW+n4p5tCOVRYhJxuqGSaycK5+t1Bs4BibYN2p7+p1PI2kpEGPCb+tp HpM2wX1TUrI01VeB94roVAhkhNRO4xsgsgcaQPvBNFHJylbn2vmFEIwlJLB4G+sr VNTlaC7uANjuBoFjopyQNLhxl/oPahI1k2z8ccGQjRjxKp5T/S8hKVniGr47m9eu WSFPDl5gqSkPwHE1RGqh2i8axBaJ97Y0MhAbRmNY2sDv7kxhC+qCKn4Xm1yEi1Mn Lw== -----END CERTIFICATE-----

Event Interface

Registering for System Events

The management of registering for notifications which occur when system events are fired is made possible through several APIs and callback functions. The following is an example of how to be notified when the “Refresh Navigator” call is made. When bindings, device names, or device media has changed, a “Refresh Navigator” call is is fired. This event is an alert for the Navigators that any cached data about the project or media may now be invalid.

Specifically the event for “Refresh Navigator” is the “OnPIP” event. To get this event, we make use of the following generic event registration calls:

RegisterSystemEvent

C4:RegisterSystemEvent(eventId, deviceId)

Creates a registration for a notification when a system event fires.

Parameter Description
eventID (num) ID value of the event. See list below.
deviceID (num) ID value of the device.

Example

C4:RegisterSystemEvent(C4SystemEvents["OnPIP"], 0)

The C4SystemEvents variable is the array of all event name to ID’s. Use deviceId 0 to register for device specific events for all devices. Some events are system wide and will be sent regardless of the device id that was registered, others use the device id to filter who gets what events.

Additionally, your driver will need to implement the OnSystemEvent method.

Useful System Event ID Values

Value Description
00 through 05 Internal System Events
06 DE_PIP, OnPIP
07 through 16 Internal System Events
17 DE_NETWORK_BINDING_ADDED, OnNetworkBindingAdded
18 DE_NETWORK_BINDING_REMOVED, OnNetworkBindingRemoved
19 DE_NETWORK_BINDING_REGISTERED, OnNetworkBindingRegistered
20 DE_NETWORK_BINDING_UNREGISTERED, OnNetworkBindingUnregistered
21 through 47 Internal System Events
48 DE_DEVICE_ONLINE, OnDeviceOnline
49 DE_DEVICE_OFFLINE, OnDeviceOffline
50 and 51 Internal System Events
52 DE_ZIPCODE_CHANGED, OnZipcodeChanged
53 DE_LATITUDE_CHANGED, OnLatitudeChanged
54 DE_LONGITUDE_CHANGED, OnLongitudeChanged
55 through 57 Internal System Events
58 DE_LOCALE_CHANGED, OnLocaleChanged
59 through 86
90 DE_DIRECTOR_IP_ADDRESS_CHANGED, OnDirectorIPAddressChanged

Note that the OnProjectChanged event was deprecated in 2.10.X due to the architectural change of using a database for persistence. There are specific events available for things such as device add, remove, and rename. These are:

AddEvent

Function called from DriverWorks driver to add a new Event. This API should not be invoked during OnDriverInit.

Available in 2.8.0.

Signature

C4:AddEvent(num,str,str)

Parameter Description
number ID value of the Event
str Event Name
str Event Description where NAME is replaced by the driver name. See Event Description example below.

Returns

True or False

True on successful addition of the Event

Example

The example below would be displayed in Composer Pro Programming as: "When the Theater->AV Switch TEST DYNAMIC 3 Event Changes" This example assumes a room of Theater and a driver named AV Switch.

C4:AddEvent(3, "TEST_DYNAMIC_3", "When the NAME TEST_DYNAMIC_3 Event Changes")

Usage Note

The AddEvent function will update an event if the event ID passed in the function is already in the driver.

DeleteEvent

Function called from DriverWorks driver to delete an Event. This API should not be invoked during OnDriverInit.

Available in 2.8.0.

Signature

C4:DeleteEvent(num)

Parametr Description
num ID value of the Event

Returns

None

Usage Note

The DeleteEvent API should not be used to remove Events which are defined in the driver's XML. Events defined in the XML are intended to be static. If an Event in the XMl needs to be deleted, it should be removed manually from the XML and the driver re-compiled and a new version assigned to it.

Events can be deleted regardless of their location within a set of Events. Empty Event IDs that result from this are acceptable.

FireEvent

Function called from DriverWorks driver to Fire a static or Dynamic Event on the driver. This API should not be invoked during OnDriverInit.

Available in 2.8.0.

Signature

C4:FireEvent(strEvent)

Parameter Description
str ID value of the Event Name

Returns

None

FireEventByID

Function called from DriverWorks driver to Fire a static or Dynamic Event (using the Event's ID Value) on the driver. This API should not be invoked during OnDriverInit.

Available in 2.8.0.

Signature

C4:FireEventByID(num)

Parameter Description
num Event ID value of the Event

Returns

None

OnDeviceEvent

This is a callback function that is sent to a driver when a device event is fired. The function delivers the Device ID for the device that fired the event and the Event's ID value.

Available in 2.9.0.

Signature

OnDeviceEvent(firingDeviceId, eventId) 

Parameter Description
num The device ID value of the device firing the event.
num The fired event's ID value.

Returns

None

Example

OnDeviceEvent(80,2)

OnSystemEvent

This is a callback function that is sent to a driver when a system event is fired. The function delivers Event specific data.

Signature

OnSystemEvent(data)

Parameter Description
data The “data” passed to this callback function is event specific and can be provided on an event by event basis as needed. In most cases, it can be ignored.

Example

function OnSystemEvent(data)
   print("System Event occurred - data: " .. data)
end

RegisterDeviceEvent

This API allows for a driver to register for another driver's event. The device ID passed is the ID of the device that is firing the event of interest. This is followed by the event ID.

Available in 2.9.0

Signature

C4:RegisterDeviceEvent(80,15)

Parameter Description
num Device ID value of the device firing the event
num ID value of the Event

Returns

None

Usage Note

Knowledge of device event ID values are required to use this API in a driver. For this reason, the use of this API is intended for event registration between two drivers which have been created in support of one another. For example, this API would be useful in a network driver that wishes to know events fired by one of its module drivers.

RegisterSystemEvent

Creates a registration for a notification when a system event fires.

Signature

C4:RegisterSystemEvent()

Parameter Description
eventID (num) ID value of the event. See table below.
deviceID (num) ID value of the device.

Example

C4:RegisterSystemEvent(C4SystemEvents["OnPIP"], 0)

Usage Note

Useful System Event ID Values

Value Description
00 through 05 Internal System Events
06 DE_PIP, OnPIP
07 through 16 Internal System Events
17 DE_NETWORK_BINDING_ADDED, OnNetworkBindingAdded
18 DE_NETWORK_BINDING_REMOVED, OnNetworkBindingRemoved
19 DE_NETWORK_BINDING_REGISTERED, OnNetworkBindingRegistered
20 DE_NETWORK_BINDING_UNREGISTERED, OnNetworkBindingUnregistered
21 through 47 Internal System Events
48 DE_DEVICE_ONLINE, OnDeviceOnline
49 DE_DEVICE_OFFLINE, OnDeviceOffline
50 and 51 Internal System Events
52 DE_ZIPCODE_CHANGED, OnZipcodeChanged
53 DE_LATITUDE_CHANGED, OnLatitudeChanged
54 DE_LONGITUDE_CHANGED, OnLongitudeChanged
55 through 57 Internal System Events
58 DE_LOCALE_CHANGED, OnLocaleChanged
59 through 86 Internal System Event
90 DE_DIRECTOR_IP_ADDRESS_CHANGED, OnDirectorIPAddressChanged

UnregisterAllDeviceEvents

This API unregisters all prior event registrations created by the RegisterDeviceEvent API.

Available in 2.9.0

Signature

C4:UnregisterAllDeviceEvents()

Parameter

None

Returns

None

UnregisterAllSystemEvents

Un-registers from all notification of all system events.

Signature

C4:UnregisterAllSystemEvents()

Parameters

None

Example

C4:UnRegisterSystemEvent()

UnregisterSystemEvent

Un-registers a notification when a system event fires.

Signature

C4:UnregisterSystemEvent(eventId, deviceId)

Parameter Description
eventID (num) - ID value of the event. See list below.
deviceID (num) - ID value of the device.

Example

C4:UnregisterSystemEvent()

UnregisterDeviceEvent

This API unregisters prior event registration created by the RegisterDeviceEvent API. The device ID passed is the ID of the device that is firing the registered event. This is followed by the event ID.

Available in 2.9.0

Signature

C4:UnregisterDeviceEvent(deviceId, eventId)

Parameter Description
num Device ID value of the device firing the registered event.
num ID value of the Event

Returns

None

Suppressing System Events

The suppress_connection_events is an optionally used device driver property that dictates whether or not Director will fire the OnDeviceOnline and OnDeviceOffline system events. While these events are not specifically handled within a driver, they can impact system performance. This is especially true when a large amount of media is present or media availability (regardless of a device’s online status) is a requirement. When these events are fired, the Room Driver clears its media cache. The media cache then must be rebuilt when a device comes back online. Unless the exercise of clearing and rebuilding the cache is needed, setting thesuppress_connection_events property to “True” is recommended.

There are two ways to implement suppress_connection_event. First, a driver developer can add the suppress_connection_events tag to the port section in the connections area of their driver. For example, to the right is an entry for an HC-250 that defines Director’s connection to Navigator:

Navigator 5115 True False True True True 0d0a

The second way to use the suppress_connection_events option is in Lua drivers. The NetConnect() function has an optional parameter that specifies whether Director should suppress OnDeviceOnline and OnDeviceOffline events for the connection. By default, Director does suppress events for all connections created this way. The events can be enabled by passing “false” for this parameter.

See the following APIs in the Serial Network Device Interface:

NetConnect

OnConnectionStatusChanged

File Interface

FileClose

Used to close an opened file handle. This API can be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:FileClose

Parameter Description
string File handle

FileCreateDir

Function to create a new directory. As part of Control4’s plan to tighten driver security, the io.popen() call has bee removed. In doing this, driver developers need to use C4:File commands to accomplish what they previously did with io.popen (). This API provides the ability to create anew directory as previously done with io.popen.

This API was introduced in O.S. Release 3.3.0

Signature

C4:FileCreateDir()

Parameters Description
string PATH_ALIAS: Path alias to an allowed location where a directory may be created.
string DirCreate: A path relative to PATH_ALIAS and the directory name for the directory to create.
Path Alias Path
SANDBOX /lua/sandbox/15 (location for driver with device id 15)
LOGGING /var/log/debug
MEDIA /media
C4Z /opt/control4/var/drivers/c4z/<driver_name>

Note that path aliases are required and cannot be replaced with the actual path.

Example

Assuming that the device id of the driver is 15, the following command will create directory "data" in /lua/sandbox/15/.

C4:FileCreateDir("SANDBOX", "data")

Assuming the device id of the driver is 15, the following command will create directory "backup" in /lua/sandbox/15/data/.

C4:FileCreateDir("SANDBOX", "data/backup")

FileDelete

This function has been modified in conjuction with O.S. release 3.3.0. As part of Control4’s plan to tighten driver security, the io.popen() call ihas been removed. In doing this, driver developers need to use C4:File commands to accomplish what they previously did with io.popen (). Two new parameters have been added to specify an allowed Alias and a sub path and file name to a file to delete.

Signature

C4:FileDelete()

Parameters Description
string filename
string PATH_ALIAS: Path representation/alias to an allowed location as to where a file may deleted.
string SubPath: A path relative to PATH_ALIAS and the file name for the file to delete.
Path Alias Path
SANDBOX /lua/sandbox/15 (location for driver with device id 15)
LOGGING /var/log/debug
MEDIA /media
C4Z /opt/control4/var/drivers/c4z/<driver_name>

Note that path aliases are required and cannot be replaced with the actual path.

Example

Assuming that the device id of the driver is 15, the following command will delete /lua/sandbox/15/data/datafile.dat.

C4:FileDelete(SANDBOX, "data/datafile.dat")

Example

C4:FileDelete("1.txt")

FileExists

Used to see if a file exists on the file system.  This function takes a file name and returns a bool if the file exists. This API can be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:FileExists()

Parameter Description
string File name

Returns

Value Description
bool True/False

Example

    bexist = C4:FileExists("1.txt")
    if (bexist) then
    -- the file is already present on the file system
    end

FileFreeSpace

Used to see how much free space exists on the file system in bytes. This API can be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:FileFreeSpace

Example

freeSpace = C4:FileFreeSpace()

FileIsValid

Used to see if a file is still valid to be written or read from. This is useful to check before or after reading to see if an end of file condition has been reached. This function returns a bool of the file status. This API can be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:FileIsValid

Example

isOkay = C4:FileIsValid(fh)

FileGetName

Used to get the name of an opened file handle.  This function takes a file handle and returns a string of the file name. An empty string is returned if the file handle is not valid. This API can be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:FileGetName

Example

name = C4:FileGetName(fh) print(“Name is “ .. name)

FileGetPos

Used to get the current read or write position for the file.  This function takes a file handle and returns the current position. This API can be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:FileGetPos

Example

pos = C4:FileGetPos(fh)

FileGetSize

File to get the current size of an opened file handle. This API can be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:FileGetSize

Parameter Description
int File handle

Return

Value Description
int Size of the file in byte size.

Usage Note

Use the c4:FileOpen() call to obtain a valid file handle

Example

fh = C4:FileOpen("test.txt")
    if (fh == -1) then
   -- the file failed to open
  return
end

fileSize = C4:FileGetSize(fh)
print("File size is " .. fileSize)

C4:FileClose(fh)

FileOpen

Used to open (if file exists) or create a new file.  This function takes a file name, returns a handle. A value of -1 is returned if an error.  This API can be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:FileOpen

Parameter Description
str File name

Returns

Value Description
int File handle

Example

See example to the right.

fh = C4:FileOpen(somefile.ext)
if (fh == -1) then
    -- the file failed to open
end

Usage Note

The C4:FileOpen() function always opens a file so that the position is at end-of-file. For example:

local f = io.open(fullfilePath, "rba")

Opening the file as illustrated above opens the file for read, binary, and append (rba). This means that anything written to the file occurs at the end of the file. This ensures that writes don't overwrite existing data.

However, this also means that attempts to read the file will not return any data because the current read position is at end-of-file.

The example given above can be corrected by using the C4:FileSetPos() function to reset the position to the beginning of the file before reading. See the example to the right.

C4:FileSetDir(parentdir)
local fh = C4:FileOpen(fileName without path)
if (fh ~= -1) then
    C4:FileSetPos(fh, 0)
    local fileSize = C4:FileGetSize(fh)
    local fileContents = C4:FileRead(fh,fileSize)
    C4:FileClose(fh)
end

FileGetOpenedHandles

Used to retrieve a table of all the opened file handles in your sandbox or nil if none are opened. The table is index = file handle and value=file name. This API can be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:FileGetOpenedHandles()

Parameters

None

Returns

Value Description
table Index= File handle
Value = File Name

Example

Closing all opened handles:

  fileHandles = C4:FileGetOpenedHandles()
  if (fileHandles) then
     for index,value in pairs(fileHandles) do
       C4:FileClose(index)
     end
  end

FileList

Used to retrieve a table of all the files that are present or nil if none exist. This API can be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:FileList

Example

Deleting all files:

  fileNames = C4:FileList()
  if (fileNames) then
     for index,value in pairs(fileNames) do
       C4:FileDelete(value)
     end
  end

FileMove

Function for or moving files within certain restrictions. As part of Control4’s plan to tighten driver security, the io.popen() call has been removed. In doing this, driver developers need to use C4:File commands to accomplish what they previously did with io.popen () This API provides the ability to move files as previously done with io.popen.

This API was introduced in O.S. Release 3.3.0

Signature

C4:FileMove()

Parameters Description
string PATH_ALIAS_FROM: is a path representation/alias to an allowed location as to where a file may be moved from.
string PATH_ALIAS_TO: A path representation/alias to an allowed location as to where it will be moved to. The following table is a list of allowed aliases.
string From: A path relative to PATH_ALIAS_FROM and the file name to be moved.
string To: A path relative to PATH_ALIAS_TO and the file name for the destination of the file. If the file name is the same then the file name does not need to be included.
Path Alias Path
SANDBOX /lua/sandbox/15 (location for driver with device id 15)
LOGGING /var/log/debug
MEDIA /media
C4Z /opt/control4/var/drivers/c4z/<driver_name>

Note that path aliases are required and cannot be replaced with the actual path.

Example

Assuming that the device id of the driver is 15, the following command will move /lua/sandbox/15/tmp/tmpFile.dat to /lua/sandbox/15/data/dataFile.dat

C4:FileMove("SANDBOX", "/tmp/tmpFile.dat", "SANDBOX", "/data/dataFile.dat")

FileRead

Used to read data from a file.  Returns an empty string if no bytes are read. This function takes a file handle and number of bytes to be read. If an end of file is reached with this read operation, a string of what data was read is returned and any subsequent calls to FileRead will return an empty string. Use the FileIsValid call to see if and end of file condition has been reached. This API can be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:FileRead

Parameter Description
int File handle
num Number of bytes to be read.

Returns

Value Description
string Read data or empty string

Example

fileData = C4:FileRead(fh, 10)

FileSetDir

In conjunction with O.S. release 3.3.0, this function is being restricted to allowed locations whereas previously it had full root access. As part of Control4’s plan to tighten driver security, the io.popen() call has been removed. In doing this, driver developers need to use C4:File commands to accomplish what they previously did with io.popen (). Prior to O.S. release 3.3.0, C4:FileSetDir had root access which would allow driver developers to modify anything on the file system.

Signature

C4:FileSetDir()

Examples

C4:FileSetDir(full_path) - Provided for backwards compatibility using allowed paths only.

C4:FileSetDir(PATH_ALIAS) - Specifying alias only.

C4:FileSetDir(PATH_ALIAS, sub_dir) - Specifying alias with a subdirectory of PATH_ALIAS

PATH_ALIAS: The path aliases are defined in the table below. When specifying a PATH_ALIAS, the alias will be replaced by the "Path" as described in the table.

Path Alias Path
SANDBOX /lua/sandbox/15 (location for driver with device id 15)
LOGGING /var/log/debug
MEDIA /media
C4Z /opt/control4/var/drivers/c4z/<driver_name>

FileSetPos

Used to set the position within the file to read or write from. This function takes a file handle and number for the new position. This API can be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:FileSetPos

Parameter Description
int File handle
num Number of position.

Example

C4:FileSetPos(fh, 50)

FileWrite

Used to write data to a file.  This function returns the number of bytes written or -1 if file is not valid (example file has been closed). This function takes a file handle, the number of bytes of the string to be written, and a string of data to be written. This API can be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:FileWrite

Parameter Description
int File handle
num Number of bytes to be written.
str Data to be written

Returns

Value Description
num Number of bytes written or -1 if file is not valid.

Example

foo = "\000\001\002\003\004\005\006\007\008\009"
bytesWritten = C4:FileWrite(fh, string.len(foo), foo)

FileWriteString

Function to write a string to an opened file handle.

Available from 1.6.0.

Signature

C4:FileWriteString

Parameter Description
int File handle
str String to be written

Returns

Value Description
int Number of bytes written or -1 if there is an error.

Usage Note

Use the C4:FileOpen() call to obtain a valid file handle.

Example

fh = C4:FileOpen("test.txt")
if (fh == -1) then
   -- the file failed to open
 return
 end

numWritten = C4:FileWriteString(fh, "test1234")
 print("Bytes written " .. numWritten)

C4:FileClose(fh)
Output: Bytes written

UnZip

Function for extracting files from a .zip archive. This API enables Lua drivers to extract one, or more, files from a .zip archive.

This API was introduced in O.S. Release 3.3.0.

Signature

C4:UnZip()

Parameters Description
string zipfile: A string containing the file path to the ZIP archive to be extracted.
string filespec: A string containing a file specification that identifies the file, or files, to be extracted. For example, the file specification "" matches all files in the archive. The file specification ".lua" indicates that only Lua files are extracted.
string destination: A string containing the path (directory) into which the archive is extracted. Directories within the archive are created relative to the specified destination.
Returns Description
boolean status: Boolean indicating whether all files were successfully extracted. true: All files were successfully extracted and no errors occurred. false: One, or more, errors occurred during extraction.
array fileset: An array containing a list of files that were successfully extracted. The path for each file is relative to the archive.
table errors: A two-dimensional table containing a list of files that failed to be extracted. Each file is associated with a string describing the error that occurred.

Examples

The examples to the right illustrate the usage of the C4:Unzip function. Note that each sample utilizes a generic Lua function called printTable that dumps the contents of a specified table. This is done to illustrate how to interpret the return values of the function. There are numerous examples of printTable online.

Example 1

result, fileset, errors = C4:Unzip("/opt/control4/var/drivers/c4z/TuneIn.c4z", "*", "/opt/control4/var/drivers/c4z/TuneIn")
print(result)
printTable(fileset)
printTable(errors)

Executing this sample produces the following output.

true
table: 0xa42c380 {
[1] => "driver.xml"
[2] => "driver.lua"
.
.
.
[287] => "www/icons/device/experience_80.png"
[288] => "www/icons/device/experience_90.png"
}
table: 0xa186b60 {
}

The output can be interpreted as follows:
The result is true, indicating that all files were extracted successfully.
The fileset array contains 288 files (truncated for display purposes) that were extracted successfully. Note that the path to each file is relative to the archive.
The errors table is empty because no errors occurred.

Example 2 ```xml result, fileset, errors = C4:Unzip("/opt/control4/var/drivers/c4z/TuneIn.c4z", "*.lua", "/opt/control4/var/drivers/c4z/TuneIn") print(result) printTable(fileset) printTable(errors)

Executing this sample produces the following output.

true table: 0xb68c5e0 { [1] => "driver.lua" } table: 0xb5cc640 { }

The output can be interpreted as follows. The result is true, indicating that all files were extracted successfully. The fileset array contains a single entry because only one file matched the file specification: "*.lua". The errors table is empty because no errors occurred. ```

Example 3

result, fileset, errors = C4:Unzip("/opt/control4/var/drivers/c4z/TuneIn.c4z", "*.gif", "/opt/control4/var/drivers/c4z/TuneIn")
print(result)
printTable(fileset)
printTable(errors)

Executing this sample produces the following output.
false
table: 0xb5cc600 {
}
table: 0xb68ab00 {
[www/composer/ico_16_tunein.gif] => "Could not open file "/opt/control4/var/drivers/c4z/TuneIn/www/composer/ico_16_tunein.gif": Not a directory"
[www/composer/ico_32_tunein.gif] => "Could not open file "/opt/control4/var/drivers/c4z/TuneIn/www/composer/ico_32_tunein.gif": Not a directory"
}
The output can be interpreted as follows.
The result is false, indicating that one, ore more, errors occurred during extraction.
The fileset array is empty because no files were extracted.
The errors table contains two entries, one for each file matching the file specification: "*.gif". Each file is associated with a string describing the error that occurred.
Example 4
result, fileset, errors = C4:Unzip("/opt/control4/var/drivers/c4z/Bogus.c4z", "*", "/opt/control4/var/drivers/c4z/Bogus")
print(result)
printTable(fileset)
printTable(errors)

Executing this sample produces the following output.

false
table: 0xb1285e0 {
}
table: 0xb652200 {
[/opt/control4/var/drivers/c4z/Bogus.c4z] => "The specified zip file does not exist"
}

The output can be interpreted as follows:
• The result is false, indicating that one, ore more, errors occurred during extraction.
• The fileset array is empty because no files were extracted.
• The errors table contains a single entry containing the zip file itself. The associated error message indicates that the specified file does not exist.

Helper Interface

AddDevice

The AddDevice API provides the ability for a driver to add a device driver to a project. The ability to specify the location of the driver within the project as well as naming the device is also supported by the API. Execution of the AddDevice/AddLocation APIs should only be initiated through user interaction from the Dealer or end user. Inadvertent use of these APIs can result in drivers or locations recursively adding themselves to a project.

Available from 3.2.0.

Signature

C4:AddDevice ()

Parameters Description
str Driver Name - Required. String of the driver name including the driver extension of .c4i or.c4z.
num Room ID - Optional. ID value of the room where the driver will reside.
str New Driver Name - Optional. String of the new name of the driver.
func Callback Function - Required. A callback function must be passed as the last parameter. The callback function can be any valid function name. In the example below, a function named OnDeviceAdded has been created. In order to receive data from the AddDevice API, this function must reside in the driver. The callback function takes two parameters: deviceId and, in the case of a Proxy Device, a table to contain all of the IDs of the Proxy devices and the Protocol Driver's ID. See the example to the right.
Callback Function Example

function OnDeviceAdded(deviceId, tDeviceInfo)
       LogTrace ("Device Added")
       LogTrace(deviceId)
       LogTrace(tDeviceInfo )
end

Returns

The API itself returns nothing. However, the callback function returns the Device ID value of the driver that was added. It will return a value of 0 upon failure.

Examples

The Inter-Device Comms suite (controller and client) in the sample_drivers directory of the SDK has been updated to show a live usage of AddDevice

1: Adding a Device to a Project without providing a Room ID.

C4:AddDevice("driver_properties.c4z", OnDeviceAdded)

In the example above, the AddDevice API will add the driver named driver_properties.c4z to the project in the same room where the driver exists.

2: Adding a Device to a Room within a Project.

C4:AddDevice("driver_properties.c4z", 38, OnDeviceAdded)

In the example above, the AddDevice API will add the driver named driver_properties to the Room in the project which has an ID value of 38.

3: Adding a Device to a Room within a Project and re-naming the driver:

C4:AddDevice("driver_properties.c4z", 38, “My New Driver”, OnDeviceAdded)

In the example above, the AddDevice API will add the driver named driver_properties to the Room in the project which has an ID value of 38. It will also rename the driver in the project to "My New Driver".

For further reference, the idc_client and idc_controller sample drivers delivered with the SDK both include auto-add functionality in their Driver Actions. See the sample_drivers directory on the SDK landing page for more information.

AddLocation

The AddLocation API provides the ability for a driver to add a location to a project. The locations that can be added are those available in a Control4 project. This includes:

Execution of the AddDevice/AddLocation APIs should only be initiated through user interaction from the Dealer or end user. Inadvertent use of these APIs can result in drivers or locations recursively adding themselves to a project.

Available from 3.2.0.

Signature

C4:AddLocation ()

Parameters Description
num ParentID Number - This parameter is the device id of the location (Site, Building, Floor) where the new location is to be added. For example, if adding a new building to a project, this parameter would be the Site ID. If adding a new room to a project, this parameter would be the Floor ID.
str Name of Location - This parameter is a string value representing the name that will be used for the newly added location. For example: "New Main Floor" or "Master Bathroom". The string passed in this parameter will be displayed in the ComposerPro project tree.
str Type of Location - This parameter is a string value that defines the type of location being added. Acceptable values include: SITE, BUILDING, FLOOR or ROOM.
str Image - This is an optional parameter that provides the ability to use a different image for the location. Valid images are based on the Type of Location. Available images are those images visible in ComposerPro. See Example 4. below for more information.

Returns

The API returns the new Location ID of the location that was added. It will return a value of 0 upon failure.

Examples

1: Adding a Site named Home to a Project:

C4:AddLocation(1, "HOME", "SITE")

In the example above, note that the AddLocation API will add the Site, “HOME” to the project. Note the use of the SITE parameter. This is the highest level available in a Control4 system. In this example, the ParentID must be the ID of the Project, which is always 1

2:  Adding a Building named "Office Building" to the Project.

C4:AddLocation(2, "Office Building", "BUILDING")

In the example above, the ParentID must be the ID of a Site

3: Adding a Floor named First Level to the Project

C4:AddLocation(3, "First Level", "FLOOR")

In the example above, the ParentID must be the ID of a Building

4: Adding a Room named Master Bathroom to the Project while using an image named "Bathroom":

C4:AddLocation(1, "Master Bathroom", "ROOM", "Bathroom")

In the example above, the room named Master Bathroom is not supported by a "Master Bathroom" image in a Control4 project. In this case, the image for Bathroom is used as it most closely matches the room being added.

For further reference, the idc_client and idc_controller sample drivers delivered with the SDK both include auto-add functionality in their Driver Actions. See the sample_drivers directory on the SDK landing page for further information.

Bind

Note the order of the parameters passed in the Bind API. Each has a "Provider" and "Consumer" designation. The Provider designation represents the Device ID value of the device providing the data within the binding. To verify if a device driver is a Provider, go to the driver's <Connections> XML.This API provides the ability to create a binding between two devices: a "Provider Device" and a "Consumer Device." The binding creation through this API is the same as manually creating a binding in ComposerPro's The <consumer> XML tag for this device's driver will be False or: <consumer>False</consumer>. Subsequently, the Provider Binding ID value is the Provider device's binding value.

Available from 2.9.0.

Signature

C4:Bind(idDeviceProvider, idBindingProvider, idDeviceConsumer, idBindingConsumer, strClass)

Parameter Description
idDeviceProvider ID value of the device providing data.
idBindingProvider Binding ID value of the binding for the Provider Device
idDeviceConsumer ID value of the device consuming data.
Class String. The binding connection class.

The Parameters with the Consumer designation represent the device that consumes data from the Provider device. The <consumer> XML tag for this device's driver will be True or: <consumer>True</consumer>. Subsequently, the Consumer Binding ID value is the Consumer device's binding value.

Returns

None

blowfishEcbDecrypt

Function to decrypt using Blowfish in ECB mode. ECB mode operates on exactly 64 bits (8 bytes) of data. This API can be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:blowfishEcbEncrypt()

Parameter Description
str Encrypted data

Returns

Value Description
str De-encrypted data.

blowfishEcbEncrypt

Function to encrypt using Blowfish in ECB mode. ECB mode operates on exactly 64 bits (8 bytes) of data. This API can be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:blowfishEcbEncrypt()

Parameter Description
str De-encrypted data.

Returns

Value Description
str Encrypted data.

CallAsync

API that makes calling functions asynchronously much easier. This API should not be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:CallAsync()

Parameter Description
str Function to be called asynchronously.

Example

print("Calling CallAsync()...")
 C4:CallAsync(function()
       print("Callback was executed.")

print("Called CallAsync().")

-- Example Output:
Calling CallAsync()...
Called CallAsync().
Callback was executed.

EvaluateExpression

EvaluateConditional evaluates the expression and returns a Boolean result. This API has 3 parameters, a logic operator and two operands. ‘value1’ is the left operand and ‘value2’ is the right operand.

Available from 2.10.0

Signature

C4:EvaluateExpression(logic, value1, value2)

Parameter Description
logic Operator used in the conditionals. The following strings are accepted:
EQUAL
NOT_EQUAL
LESS_THAN
GREATER_THAN
GREATER_THAN_OR_EQUAL
value 1 Left operand of the expression
value 2 Right operand of the expression

Returns

True or False

Example

C4:EvaluateExpression("GREATER_THAN_OR_EQUAL", 50, 0)

In the example above, the expression could be written as “result = (50 >= 0)” and would evaluate to result being equal to “true”.

GetAllCodeItems

This function returns all Code Items within the project.

This API was introduced in O.S. Release 3.3.0

Signature

C4:GetAllCodeItems()

Parameters

None

Returns Description
Table LUA table with all of the code items that exist in the active project. Table contents will vary based on the code items stored in the system.

Example

GetAllCodeItems returns a table with the device ID, the code item, and the event ID for each of the device ID/event ID pairs in the system. The table contains the following key-value pairs:

Key Value
deviceid The device ID a code item is for.
codeitem A table that contains the code item information.
eventid The event ID a code item is for.

The table returned by the GetAllCodeItems API (that was stored in codeItems) might look like the table to the right.

{
    ["event_mgr"] = {
        [1] = {
            ["deviceid"] = 1,
            ["codeitem"] = {
                ["enabled"] = true,
                ["cmdcond"] = {
                    ["xml"] = 
                } ,
                ["creator"] = 0,
                ["device"] = 0,
                ["type"] = 1,
                ["display"] = ,
                ["subitems"] = {
                    [1] = {
                        ["enabled"] = true,
                        ["cmdcond"] = {
                            ["xml"] = <devicecommand owneridtype="" owneriditem="-1"><command>ON</command><params/></devicecommand>
                        } ,
                        ["creator"] = 0,
                        ["device"] = 19,
                        ["type"] = 1,
                        ["display"] = Turn on the NAME,
                        ["subitems"] = {} ,
                        ["creatorstate"] = ,
                        ["id"] = 1,
                    } 
                } ,
                ["creatorstate"] = ,
                ["id"] = 0
            } ,
            ["eventid"] = 1,
        } ,
        [2] = {
            ["deviceid"] = 100100,
            ["codeitem"] = {
                ["enabled"] = true,
                ["cmdcond"] = {
                    ["xml"] = 
                } ,
                ["creator"] = 0,
                ["device"] = 0,
                ["type"] = 1,
                ["display"] = ,
                ["subitems"] = {} ,
                ["creatorstate"] = ,
                ["id"] = 0,
            } ,
            ["eventid"] = 2,
        }
    }
}

GetBootID

This function returns a string that contains an ID which is unique for the current kernel instance. When the controller is re-booted, the ID will change. The returned value is the same value as the one stored on Linux at:

/proc/sys/kernel/random/boot_id

This API was introduced in O.S. Release 3.3.0

Signature

C4:GetBootID()

Parameters

None

Returns Description
string Current kernel instance.

Example

GetBootID returns a string with the current boot ID for the kernel. An example of the value that can be returned is:

1525a67e-b7bd-4a68-8919-dd65e7f3861a

GetCodeItems

This function returns Code Items for a specified device and event.

This API was introduced in O.S. Release 3.3.0

Signature

C4:GetCodeItems ()

Parameters Description
num device ID value
num event ID value
Returns Description
Table LUA table with the code items for the passed device ID and event ID. This will vary depending on parameters provided and the code items stored in the system.

Example

GetCodeItems returns a table with an entry for the device ID and event ID that were provided. The table contains the following key-value pairs :

Key Value
enabled true/false. Is this code item enabled?
cmdcond A condition that needs to be met for this code item to be called.
creator The ID of the entity that created this code item.
device The device ID for the code item.
type See "Code Item Types" section below
display Description of the code item
subitems Additional code items related to this one.

Code Item Types

Description Value
Container 0
Command 1
Condition 2
Loop 3
Else 4
Comment 5
Operator 6

The table that is returned by the GetCodeItems command (that was stored in codeItems) would look like the table to the right.

{
    ["codeitems"] = {
        [1] = {
            ["enabled"] = true,
            ["cmdcond"] = {
                ["xml"] =
            } ,
            ["creator"] = 0,
            ["device"] = 0,
            ["type"] = 1,
            ["display"] = ,
            ["subitems"] = {
                [1] = {
                    ["enabled"] = true,
                    ["cmdcond"] = {
                        ["xml"] = <devicecommand owneridtype="" owneriditem="-1"><command>ON</command><params/></devicecommand>
                    } ,
                    ["creator"] = 0,
                    ["device"] = 19,
                    ["type"] = 1,
                    ["display"] = Turn on the NAME,
                    ["subitems"] = {} ,
                    ["creatorstate"] = ,
                    ["id"] = 1,
                }
            } ,
            ["creatorstate"] = ,
            ["id"] = 0
        }
    }
}

GetC4iDir

Function that will return the directory path on the controller where driver.c4i files reside.

Available from 2.10.0

Signature

C4:GetC4iDir()

Parameters

None

Returns

Value Description
str Directory path.

GetC4zDir

Function that will return the directory path on the controller where driver.c4z files reside.

Available from 2.10.0

Signature

C4:GetC4zDir()

Parameters

None

Returns

Value Description
str Directory path.

GetLogDir

Function that will return the directory path on the controller where log files reside.

Available from 2.10.0

Signature

C4:GetLogDir()

Parameters

None

Returns

Value Description
str Directory path.

getPushSettings

A Boolean API that returns the project’s current setting for the “Push Settings from Project” checkbox in Composer Pro’s Project properties screen. True equals a populated checkbox. False equals an un-populated checkbox. This is useful for determining if a driver can push settings to a device (true) or if settings will be sent from the device to the project (false).

Available from 2.7.0.

GetSandboxDir

Returns the directory where the LUA driver will store its files.

Available from 2.9.0

Signature

GetSandboxDir()

Example

print(C4:GetSandboxDir())

Outputs:

/control4/drivers/lua/sandbox/88

Note that the value of 88 in the example above is the Device ID for the driver.

GetTimeZone

Returns the Project's current Time Zone in the form of a LUA string. If there is no Time Zone set for the project, such as in the case of an unidentified controller, an empty string is returned.

Available from 3.0.0

Signature

C4:GetTimeZone ()

Parameters

None

Returns

Value Description
str Time Zone in a string format.

Examples of return strings are: US/Mountain US/Pacific US/Samoa

Usage Note

The string value returned will be same as the Project value set in: Composer -> Project Settings -> Time Zone field.

hexdump

Prints out the values of a string in both hex and ascii representation. All characters that are not ‘A-Z’ or ‘0-9’ are printed as a ‘.’ in the ascii representation. The print goes to the Lua tab on the properties page of the driver. This API can be invoked during OnDriverInit.

Available from 1.6.0

Signature

hexdump(strDump)

Parameter Description
strDump Text to print out in a hexdump.

Returns

None

Example

hexdump(tohex("00 ff de ad be ef ") .. "Test Text")

Prints out the following:
00000000  00 FF DE AD BE EF 54 65  ......Te
00000008  73 74 20 54 65 78 74     st.Text

OnBindingChanged

Function called by Director when a binding changes state (bound or unbound).

Available from 2.9.0

Signature

OnBindingChanged (idBinding, strClass, bIsBound, otherDeviceID, otherBindingID)

Parameter Description
idBinding ID of the binding whose state has changed.
str Class of binding that has changed. A single binding can have multiple classes: COMPONENT, STEREO, etc. This indicates which has been bound or unbound.
bIsBound Whether the binding has been bound or unbound.
otherDeviceID This Device ID value represents the Device ID for the device that makes up the other half of this binding.
otherBindingID This Binding ID value represents the Binding ID for the device represented by the otherDeviceID value in the parameter above.

Returns

None

Usage Note

Protocol drivers do not get OnBindingChanged notifications for AV and Room bindings being bound, only control type bindings (Serial, IR, etc.). It is intended to be used specifically for when serial bindings are made, so the driver knows it can send initialization, etc. to the now-connected device.

ParseXML

Helper function which turns a XML document into a .lua table of parsed XML data. This API can be invoked during OnDriverInit.

Available from 2.7.0

Signature

C4:ParseXml (str)

Parameter Description
str XML in string format

Returns

Value Description
Table Lua Table.

Example

     function ParseProxyCommandArgs(tParams)
       local args = {}
       local parsedArgs = C4:ParseXml(tParams["ARGS"])
       for i,v in pairs(parsedArgs.ChildNodes) do
              args[v.Attributes["name"]] = v.Value
       end
       return args
      
end

print

Function called from DriverWorks driver to prints items out the drivers’ properties page console. Note that for convenience, the print function can be called without prefacing with "C4:" This API can be invoked during OnDriverInit.

Available from 1.6.0.

Signature

print(strPrintText)

Parameter Description
str Text to print.

Returns

None

Usage Note

The Lua output window in ComposerPro does not necessarily display output in the order in which code is actually executed. The print API is a function implemented in Lua which causes the driver to send a DataToUI message.

DataToUI commands are not guaranteed to be in any particular order. ComposerPro simply captures this DATA and displays it. If the order of data appearing in the ComposerPro Lua window is important, Control4 suggests the use of the Director log.

RecordHistory

Helper Function that writes history events to the History Agent database.

Available from 1.6.0.

Signature

C4:RecordHistory(severity, eventType, category, subcategory, description)

Parameter Description
str Severity: Valid parameters include: “Critical”, “Warning”, or “Info"
str eventType: Describes the type of event within a category. Each category would define specific types of history event. For example, the Security category could define the following event types: Arm, Disarm, Open, Close, Alarm, etc.
str Category: Represents the high level logical group that the device or source belongs to. These categories may correlate to Navigator categories, but could include additional categories. For example: Security, Lighting, Comfort, System etc.
str Subcategory: An optional subcategory can be included. The sub category provides additional event criteria that may be used to query for events.
str Description: Brief description.

Returns

None

Example

C4:RecordHistory(“Critical”,"Disarm”,"Security”,”Front Door”,”The front door was disarmed.")

tohex

Function called from DriverWorks driver to convert a text string of hex into a string with hex values in it. Typically used when a protocol sends commands that are hex values. Note that for convenience, the print function can be called without prefacing with C4: This API can be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:tohex(strHex)

Parameter Description
str Text to convert to binary hex.

Returns

None

Example

Store the HEX code for a discrete Power On command for a Mitsubishi TV:

POWER_ON = tohex("DF 80 70 F8 02 00 00")

tonumberloc

The Lua tonumber() function included in the Lua Library is locale specific. This can cause issues where the Control4 system is set to a locale where the decimal separator is different from what is returned by the target device. For example, if the target device sends the Control4 driver a string of 23.4 (23 decimal 4) but the locale expects this to be 23,4 (23 comma 4) then tonumber("23.4") will fail.  This problem often occurs in drivers where the UI uses decimal values and can occur with any proxy.

Driver writers must ensure that their drivers will not fail in these circumstances. To assist with this, Control4 has provided a function: tonumberloc(). This function is included in the driver templates beginning OS release 2.8.0 and its use ensures this problem does not occur.  Driver writers are advised to usetonumberloc()  in place of tonumber() in their code.

Available from 1.6.0.

Signature

tonumber_loc()

Example


function tonumber_loc(str, base)
        local s
        local num
        if type(str) == "string" then
                s = str:gsub(",", ".") -- Assume US Locale decimal separator
                num = tonumber(s, base)
                if (num == nil) then
                        s = str:gsub("%.", ",") -- Non-US Locale decimal separator
                        num = tonumber(s, base)
                end
        else
                num = tonumber(str, base)
        end
        return num
end

ToStringLocaleC

String helper function to convert a number to a string using the ‘C’ locale regardless of the locale setting of the Control4 Operating System. Some countries use commas instead of decimal points for floating point numbers. Lua ‘tostring’ command and string concatenation (..) with a number variable will convert the decimal value from a decimal point to a comma in some countries (locales). There may be instances where you do not want this conversion to take place and want the floating-point number to always be represented using a decimal point as opposed to a comma. In these cases, the C4:ToStringLocaleC(num) command can be used to convert the number to a string using decimal points.

Available from 1.6.0.

Signature

C4:ToStringLocaleC (num)

Parameter Description
num The number to convert (may be a floating-point number)

Example

The xml schema for extras functionality for thermostat proxy drivers requires that all floating-point numbers be represented using a period for the (decimal point). Using string concatenation to generate the extras xml would produce xml with the comma for the floating-point number if the locale is set to a country that uses commas.   For example, if you have a thermostat that supports an “Auto Temperature” that is not supported by the proxy that you would like displayed under “Extras” in the Thermostat UI you would need to generate the “Extras” xml to send to the UI. If the temperature represented is a floating-point number then when this number is converted to a string with ‘tostring’ or string concatenation (..), it would be converted to a number represented with a comma. In this case you would want to use the C4:ToStringLocaleC() API to convert the floating number appropriately.

unbind

This API provides the ability to unbind bound devices. The unbinding of the devices binding through this API is the same as manually unbinding two devices in ComposerPro's Connections area. Note the parameters passed in the API. Both have "Consumer" designation. These parameters represent the device that consumes data from the Provider device. To verify if a device driver is a Consumer, go to the driver's <Connections> XML. The <consumer> XML tag for this device's driver will be True or: <consumer>True</consumer>. Subsequently, the Consumer Binding ID value is the Consumer device's binding value.

Available from 2.9.0.

Signature

C4:Unbind(idDeviceConsumer, idBindingConsumer)

Parameter Description
num idDeviceConsumer - ID value of the device consuming data.
num idBindingConsumer - Binding ID value of the binding for the Consumer Device

Returns

None

Example

C4:Unbind(81,1)

UUID

This API generates a UUID (Universally Unique IDentifier) as described in RFC 4122. The type of UUID that is generated depends on the arguments passed into the function.

Available from 3.3.0

Signature

C4:UUID(Type,[Value1,Value2,Value3])

Parameter Description
Type Specifies the type of UUID to be generated: NIL, String, Name or Random. See below for further information.
Value1, Value2, Value3 Values passed to the remaining arguments depend on the type of UUID to be generated. Please see the list below for additional information about required arguments.

The following section identifies the different types of UUIDs that are supported:

NIL

Required Argument: (”NIL”) A NIL UUID is one in which all bits are zero. It is represented as a string containing all zeros: 00000000-0000-0000-0000-000000000000

String

Required Argument: (”STRING”) A string containing the data to be formatted as a UUID. The String UUID type takes an input string and formats its contents as a UUID. The format of the string must match the following regular expression:

^({)?([0-9a-fA-F]{8})(?-)?([0-9a-fA-F]{4})(?(DASH)-)([0-9a-fA-F]{4})(?(DASH)-)([0-9a-fA-F]{4})(?(DASH)-)([0-9a-fA-F]{12})(?(1)})$

More generally, the following formats are accepted, where h is a valid hexadecimal character:

hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh

{hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh}

hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh

{hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh}

Name

Required Argument: (”NAME”)

Hash: The hashing algorithm to use when generating the UUID. Valid values including the following:

Algorithm Description
MD5 Produces a version 3 UUID (UUID3)
SHA1 Produces a version 5 UUID (UUID5)

Namespace: A string containing the namespace to be used when generating the UUID. The value must be one of the following as described in Appendix C of RFC 4122:

Namespace Description
DNS The value of the Name argument (below) is a fully-qualified domain name.
URL The value of the Name argument (below) is a URL.
OID The value of the Name argument (below) is an ISO OID (Object IDentifier).
X500DN The value of the Name argument is an X.500 DN.

Name: A string containing the content from which the UUID is derived.

Random

Required Argument: (”RANDOM”) Generates a random version 4 UUID (UUID4). The generator utilizes entropy provided by the operating system. For example: (i.e., /dev/urandom).

Returns

The function may return multiple values. On success, the function returns a string containing the newly generated UUID. On failure, the function returns nil and a string describing the failure.

XmlEscapeString

"Escapes" the passed in string rendering any XML characters (only &, <, and >) in the string as characters that are valid in an XML value. This API should not be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:XmlEscapeString(strRawInput)

Parameter Description
str strRawInput: Raw input string, with possibly invalid characters for an XML value.

Returns

Value Description
str strEscaped: The passed in string, with all XML characters properly escaped.

Example

Builds an XML string with a string that could have invalid XML characters in it:

strXmlListItem = "<text>" .. C4:XmlEscapeString .. "</text>"

Inbound Driver Interface

InBound Driver Interface

The functions listed below represent Lua functions that are not Control4 APIs but are however included in this documentation. The functions below are implemented within a DriverWorks driver and can be called by an API, Director or another external process.

For example, the Lua function UIRequest isn't a Control4 API. However, it is an InBound Driver Function that needs to be implemented in your driver if you intent to use the Control4 API:SendUIRequest. SendUIRequest sends a request to another driver. It uses the proxy or protocol ID value of the driver as a means to target the driver where the request will be sent. The driver receiving the SendUIRequest must have the InBound Driver Function UIRequest configured, which will contain the return values requested by the SendUIRequest call.

Here is an example of using SendUIRequest in a driver:

C4:SendUIRequest(231, "GET_MY_DRIVER_DATA", tParams)

In this example, the API contains a value of 231. This is the proxy ID value of the driver where the request is being sent. This is followed by a request called GET_MY_DRIVER_DATA. This is an expected request by the driver receiving the SendUIRequest. A table of parameters follows the command.

To the right is an example of the required UIRequest InBound Driver Function found in the driver receiving the SendUIRequest. In this example, when the request is received it takes the values in the tParams table and, if they are not a specified value of 640 or 480, multiplies them by 10. It then formats the values into XML and returns them through retValue to the driver that initiated the SendUIRequest.

function UIRequest(sRequest, tParams)
    tParams = tParams 
    local param_x = tonumber(tParams["PARAM_X"]) or 640
    local param_y = tonumber(tParams["PARAM_Y"]) or 480
               
         local value_x = param_x  10
         local value_y = param_y  10
               
         local retValue = "<driver_data>"
         retValue = retValue .. "<value_x>" .. value_x .. "</value_x>"
         retValue = retValue .. "<value_y>" .. value_y .. "</value_y>"
         retValue = retValue .. "</driver_data>"
               
    return retValue
end

--The XML below is the returned value. <driver_data>`     <value_x>10240</value_x>     <value_y>7680</value_y> </driver_data>

List of InBound Driver Functions:

IR Interface

SendIR

Function called from DriverWorks driver to send an IR Code. This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:SendIR(idBinding,idIRCode)

Parameter Description
num idBinding: IR Binding ID to send the IR Code.
num idIRCode: ID of the IR Code to send from .c4i
num idBinding:Proxy Binding ID. (optional)

Returns

None

Usage Note

The IR code to send must be declared as an <ircode\> in the <irsection\> section of the driver file.

SendIRStart

Causes Director to start sending the specified IR Code out the specified binding. This is typically used on button press events. This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:SendIRStart(idBinding, idBinding, idIRCode)

Parameter Description
num idBinding: Proxy Binding ID.
num idBinding: Binding ID to send the IR Code.
num idIRCode: Id of the IR Code to start sending from the driver.

Returns

None

Usage Note

Failure to call the SendIRStop function will cause the IR code to be sent continually, which (in the case of volume ramps) could be catastrophic to equipment. The IR code to send must be declared as an <ircode\> in the <irsection\> of the driver file.

Example

This example starts sending the specified IR Code out the specified IR Binding:

C4:SendIRStart(1, 22)

SendIRStop

Causes Director to stop sending the specified IR Code out the specified binding. This is typically used on button release events. This API can be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:SendIRStop(idBinding,idBinding, idIRCode)

Parameter Description
num idBinding: Proxy Binding ID.
num idBinding: Binding ID to send the IR Code.
num idIRCode: Id of the IR Code to start sending from the driver file.

Returns

None

Usage Note

Usage Note: The IR code to send must be declared as an <ircode\> in the <irsection\> section of the driver file.

Example

This example stops sending the specified IR Code out the specified IR Binding:

C4:SendIRStop(1, 22)

JSON Interface

c4json.null

c4json is a global object that is used by the JSON encoder/decoder.

null Represents a JSON null value.

c4json.null can be used to insert a null value into a JSON document (encode), or test for a null value that was encountered in a JSON document (decode).

Json:Encode

JSON function that takes the data in the Lua tCommand table and encodes it into a JSON formatted command string representing a Lua object.  On success, this function returns a single value which is as designed. On failure, the function returns two values:

  1. nil
  2. A string describing the error.

This API should not be invoked during OnDriverInit.

Parameter Description
value The Lua object to be encoded. Must be one of the following types: number, string, boolean, table. Tables can contain any combination of types (including nested tables) provided that all items are one of the following types: number string, boolean. Note that c4:JsonEncode will fail if any table (or nested table) contains any of the following types: lightuserdata, userdata, function, thread.
formatted Optional. A boolean flag value indicating whether the resulting JSPN string is formatted using newlines and indentations. The default value is False when omitted.
encodeArrays Optional. A boolean flag value indicating whether the tables are encoded as JSON arrays. The default value is False when omitted.
symmetric Optional. A boolean flag value indicating whether the resulting JSON objects consist of name/value pairs in which the name must be a string (i.e, double quotes).

Where necessary, the encoder uses the following fabricated names:

Primitive Type Fabricated Name
Number :number:
String :string:
Boolean :boolean:
Array Index :index:

Examples

Primitive
local Foo = "Bar"
local Result = c4:JsonEncode(Foo)

The preceding example yields the following JSON string: {":string:":"Bar"} This occurs because "Foo" is a primitive type (i.e., String). Unfortunately, the name of a single primitive value is unknown to the encoder so it must use a fabricated name that identifies the type. This is necessary because the JSON specification requires that all JSON objects consist of name/value pairs in which the name must be a string (i.e., double quotes).

Note that you'll need to use a Lua table in order to provide a JSON string that includes the name of the value. Consider the following example.

Table
local MyTable = {
    Foo = "Bar"
}

C4:JsonEncode(MyTable)

The preceding example produces the following JSON string: {“Foo”:”Bar”} It is also possible to control whether the resulting JSON string is formatted using newlines and indentations.

Unformatted
local Foo = {
    Biz = "Baz",
    Qux = "Norf"
}

C4:JsonEncode(Foo)

The preceding example yields the following JSON string: {“Biz”:”Baz”,”Qux”:”Norf”}. This might be acceptable when the string is to be used in processes that don't involve humans, such as invoking a REST service. If readability is important, however, provide the formatted (second) parameter.

Formatted
local Foo = {
    Biz = "Baz",
    Qux = "Norf"
}

C4:JsonEncode(Foo, true)

With this example, the resulting JSON string is formatted as:

{
    "Biz" : "Baz"
    "Qux" : "Norf"
} 

The encodeArrays (third) parameter provides control over how tables are encoded. In certain cases it might be necessary to specify that tables are encoded as JSON arrays. Note that a Lua table is considered to be an array when each key is a non-negative integer greater than zero (k > 0). Consider the following code.

Object
local Foo = {
    "One",
    "Two",
    "Three",
    "Four",
}

C4:JsonEncode(Foo, true)

By default, tables are encoded using JSON objects, so the preceding example produces the following formatted JSON string:

{
    "1" : "One"
    "2" : "Two"
    "3" : "Three"
    "4" : "Four"
}

This encoding results for two reasons: First, the table is a Lua array. Each entry corresponds to a numeric key. Second the JSON specification requires that an object consist of name/value pairs in which each name must be a string (i.e., double quotes). As a result, each numeric key is converted to a string. This same table can also be represented as a JSON array.

Array
local Foo = {
    "One",
    "Two",
    "Three",
    "Four",
}

C4:JsonEncode(Foo, true, true)

With the encodeArrays (third) parameter set to true, the encoder yields the following JSON string: [ “One”, “Two”, “Three”, “Four” ]

It is important to note that the encodeArrays parameter affects only tables that are Lua arrays. Consider the following code.

Non-Array
local Foo = {
    Biz = "Baz",
    Quz = "Norf"
}

C4:JsonEncode(Foo, true, true)

Although the encodeArrays parameter was set to true, the resulting JSON string is encoded as JSON object:

{
    "Biz" : "Baz",
    "Qux" : "Norf"

}

This occurs because the Lua table was not an array (i.e., contained at least one non-numeric key). Attempting to encode this table as an array would result in an invalid JSON string.

The symmetric (fourth) parameter specifies whether to use symmetric encoding. When symmetric encoding is enabled, the encoder places certain markers within the resulting JSON string. These markers make it possible to decode a JSON string back into the original (equivalent) object. Symmetric encoding (markers) is necessary due to ambiguities that arise when encoding a Lua object. Consider the following code.

Non-Symmetric
local Foo = {
    "One",
    {
        Two = "Two",
        Three = "Three",
    }
}

C4:JsonEncode(Foo, true, false)

While this accurately represents the Lua object as a JSON string, given the rules of Lua arrays and JSON, it cannot be decoded back into its original (equivalent) table. Rather, decoding this string will produce the following Lua table.

local Bar = {
    ["1"] = "one",
        ["2"] = {
        Two = "Two",
        Three = "Three",
    }
}

Note that the original numeric keys are now strings. Enable symmetric encoding corrects this problem by introducing markers into the resulting JSON string.

Symmetric
local Foo = {
    "One",
    {
        Two = "Two",
        Three = "Three",
    }
}

C4:JsonEncode(Foo, true, false, true)

With the symmetric parameter set to true, the encoder produces the following JSON string:

{
    ":index:1 : "One",
    ":index:2" : "Two" : {
        "Three" : "Three",
        "Two" : "Two"
    }
}

Note the use of the ":index:" markers. These markers specify that the first element, "One", is located at the first numeric index. Similarly, the second element, "Two", is located at the second numeric index. Decoding this JSON string produces the original Lua table. It is important to note that Lua doesn't guarantee any particular order when enumerating the elements of a table. As described in the documentation for the Lua next function. The order in which the indices are enumerated is not specified, even for numeric indices.

Json:Decode

JSON function that takes data from the JSON formatted string message and decodes it into the Lua table. On success, this function returns a single value which is as designed. On failure, the function returns two values:

  1. nil
  2. A string describing the error.

This API should not be invoked during OnDriverInit.

Signature

C4:JsonDecode(json)

Parameter Description
json A string containing the JSON to be decoded.An error will be raised if the string contains invalid JSON. The actual value returned depends on the value of the json parameter and can be any of the following: Number, String, Boolean, Table
decodeNull Optional. Boolean flag value indicating how null values are decoded. By default (false), null values are converted to an empty table. A value of true specifies that null values are decoded as a lightuserdata object with a value of null.

Returns

A value decoded from the specified JSON string.

Examples

Primitive C4:JsonDecode("{":number:":42}")

The preceding example will return a Number with the value: 42. In most cases, however, the decoder will return a table. Consider the following code:

Table
local value  = '{"Contents":["Asia", "Africa", "North America", "South America", "Europe", "Australia"]}'
local Foo = C4:JsonDecode(value)

The preceding example produces the following Lua table:

local Foo = {
    "Continent" = {
        "Asia",
        "Africa", 
        "North America", 
        "South America", 
        "Europe", 
        "Australia"
    }
}

Log Interface

DebugLog

Function called from DriverWorks driver to send messages to the following log files: director.log and driver.log. This API can be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:DebugLog(strLogText)

Parameters Description
str Log text

Returns

None

Examples

function Log:Alert(strDebugText)
   self:Print(0, strDebugText)
end

function Log:Error(strDebugText)
   self:Print(1, strDebugText)
end

function Log:Warn(strDebugText)
   self:Print(2, strDebugText)
end

function Log:Info(strDebugText)
   self:Print(3, strDebugText)
end

function Log:Trace(strDebugText)
   self:Print(4, strDebugText)
end

function Log:Debug(strDebugText)
   self:Print(5, strDebugText)
end

ErrorLog

Function called from DriverWorks driver to send messages to the following log files: director.log and driver.log.

Available from 1.6.0

Signature

C4:ErrorLog(strLogText)

Example

Here is an example using a variable called "lightLevel" to send an error log when a light level exceeds the value of 100:

If (lightLevel > 100) then
   C4:ErrorLog(ERROR: light level out of range)
end

TCPClient Interface

CreateTCPClient

Generally, the class cleans up any resources associated with it.  For example, when the object is no longer referenced, it will cleans it up.  However, there are a few exceptions:  When the class is performing an asynchronous operation, e.g. a connect request, it will remain alive until the appropriate event callback function is called. 

For instance, if you call the Connect() method, the class will remain alive until it either called the OnConnect (and OnResolve) callback function, or the OnError callback function, even if your lua code does not have any reference to the class during that time period.  The same applies to the time period between calling one of the Read() methods and the corresponding OnRead() or OnError() callback, and in between calling the Write() method and the OnWrite() or OnError() callback. This API should not be invoked during OnDriverInit.

Available in 1.6.0

 

Example

function PullHttpPage(host, path, timeout, done)
 local timer
 local completed = false
 local complete = function(data, errMsg)
  if (not completed) then
   completed = true
   if (timer ~= nil) then
    timer:Cancel()
   end
   done(data, errMsg)
  end
 end
 local readingHeaders, needBytes, response, allReceived
 local cli = C4:CreateTCPClient()
  :OnConnect(function(client)
   local remote = client:GetRemoteAddress()
   print("Connected to " .. remote.ip .. ":" .. remote.port)
   client:Write("GET " .. path .. " HTTP/1.0\r\nHost: " .. host .. "\r\n\r\n"):ReadUntil("\r\n")
   readingHeaders = true
   needBytes = nil
   response = ""
   allReceived = false
  end)
  :OnResolve(function(client, endpoints, choose)
   -- Implementing this callback is optional
   print("Resolved.  Artificially delay choosing endpoint by one second...")
   C4:SetTimer(1000, function(_)
    --choose(1) -- This would choose the first endpoint in the endpoints array
    --choose(0) -- Abort the connection request
    choose() -- Default behavior, this chooses the first endpoint (if available)
   end)
  end)
  :OnDisconnect(function(client, errCode, errMsg)
   if (errCode ~= 0) then
    complete(nil, "Disconnected with error " .. errCode .. ": " .. errMsg)
   elseif (needBytes == nil) then
    complete(nil, "Disconnected and no or invalid response received")
   elseif (needBytes > 0) then
    complete(nil, "Disconnected and received partial response")
   end
  end)
  :OnRead(function(client, data)
   if (readingHeaders) then
    if (data ~= "\r\n") then
     -- Look for the Content-Length header
     local sep = string.find(data, ":", 1, true)
     if (sep ~= nil and sep > 1) then
      local header = string.lower(string.sub(data, 1, sep - 1))
      local value = string.sub(data, sep + 1, -2)
      if (header == "content-length") then
       needBytes = tonumber(value)
      end
     end
     client:ReadUntil("\r\n")
    else
     readingHeaders = false
     if (needBytes ~= nil and needBytes > 0) then
      -- Got all headers, now read the body
      client:ReadUpTo(needBytes)
     else
      -- No body to read
      client:Close()
      if (needBytes == 0) then
       complete("")
      end
     end
    end
   else
    -- Append the body data
    response = response .. data
    needBytes = needBytes - string.len(data)
    if (needBytes > 0) then
     -- We haven't received everything, read more
     client:ReadUpTo(needBytes)
    else
     -- We received the entire body
     client:Close()
     complete(response)
    end
   end
    end)
  :OnError(function(client, errCode, errMsg)
   complete(nil, "Error " .. errCode .. ": " .. errMsg)
  end)
  :Connect(host, 80)
 if (timeout > 0) then
  timer = C4:SetTimer(timeout, function()
   cli:Close()
   complete(nil, "Timed out!")
  end)
 end
end
print("Downloading http://example.com/ ...")
PullHttpPage("example.com", "/", 5000, function(info, err)
 if (info ~= nil) then
  print("GOT: " .. tostring(info))
 else
  print("ERROR: " .. err)
 end
end)

Close

This method closes an established connection, or cancels a pending resolve or connection request. If a resolve or connection request is canceled, the OnError callback function will get called. This API should not be invoked during OnDriverInit. Once you call this method, no more data will be read from the socket and you can no longer write additional data to the socket. Also, the OnWrite callback will not be called anymore, even if the flush argument is set to true.

Available in 1.6.0

Signature

C4:Close(flush)

Parameters Description
bool flush: Value that indicates whether any queued-up write requests should be sent out prior to closing the connection.

Connect

This method initiates a connection request to a host and service/port. If a connection request is already in progress, this function returns nil. This API should not be invoked during OnDriverInit.

Available in 1.6.0

Signature

C4:Connect(host, service)

Parameters Description
host IP address or host name to connect to.  It can also be one of these special values: "!local" or "!loopback" Connect over the loopback device service is the port number or a string with the service (e.g. 80 or "http").

 

Returns

This method returns a reference to itself, or nil in case of an error.

GetLocalAddress

This method returns a table with the IP address and port of the local endpoint. This API should not be invoked during OnDriverInit.

Available in 1.6.0

Signature

C4:GetLocalAddress()

Parameters

None

Returns

Value Description
table IP address of the local endpoint 
Port number of the local endpoint

GetRemoteAddress

This method returns a table with the IP address and port of the remote endpoint. This API should not be invoked during OnDriverInit.

Available in 1.6.0

Signature

C4:GetRemoteAddress()

Parameters

None

Returns

Value Description
table IP address of the remote endpoint
Port number of the remote endpoint

OnConnect

This method sets a callback method that will be called once the endpoint has been chosen and the connection is successfully established.

Available in 1.6.0

Signature

C4:OnConnect(func)

Parameters Description
func Function should have this function signature: function(client). The client is this C4LuaTCPClient instance

Returns

This method returns a reference to itself.

OnDisconnect

This method sets a callback method that will be called when the client gets disconnected.

Available in 1.6.0

Signature

C4:OnDisconnect(func)

Parameters Description
func Function should have this function signature: function (client, errCode, errMsg)

Usage Note

Returns

This method returns a reference to itself.

OnError

This method sets a callback method that will be called when an error happens during an asynchronous operation.

Available in 1.6.0

Signature

C4:OnError(func)

Parameters Description
func Function should have this function signature: function (server, code, msg)

Usage Note

Returns

This method returns a reference to itself.

OnRead

This method sets a callback method that will be called once data has been read on the socket.  If you would like to keep reading more data, you should call one of the Read() methods prior to returning from this callback function.

Available in 1.6.0

Signature

C4:OnRead(func)

Parameters Description
func Function should have this function signature: function (client, data)

Usage Note

Returns

This method returns a reference to itself.

OnResolve

This method sets a callback method that is called once the host/service has been resolved.  If implemented, it allows you to choose a particular endpoint to connect to, or to cancel the connection request.

Available in 1.6.0

Signature

C4:OnResolve(func)

Parameters Description
func Function should have this function signature: function(client, endpoints, choose)

Usage Note

function([index])

Using this closure is optional and can be used to delay making a choice. The index argument is of type number, and it is optional.  If not provided, default behavior is requested (first endpoint, if available). If the index argument is provided, it should be an index into the endpoints array.  If the index argument is 0, the listen request will be canceled and the OnError callback will be called with an invalid argument error (code 22). func may return a number value that describes the index into the endpoints array, which will be the endpoint that the server should listen on. If this value is 0, the listen request will be canceled and the OnError callback will be called with an invalid argument error (code 22). If the function doesn't return anything, default behavior is chosen unless the choose function is being used to delay making a choice.  Note that if you call the choose function prior to returning from this callback function, that choice will be used rather than whatever the callback may return (if anything). Also, note that modifying the endpoints array (or any table in it) in any way has no effect.|

Returns

This method returns a reference to itself.

Option

This method sets a socket option. This API should not be invoked during OnDriverInit.

Available in 1.6.0

Signature

C4:Option(name, value[, ...])

Parameters Description
str Name is a string specifying the option to set.  It can be one of the following:
”keepalive": Enables or disables the socket's keep-alive option based on the boolean value supplied in the value argument.
”nodelay": Enables or disables the socket's no-delay option based on the boolean value supplied in the value argument.
”linger": Enables or disables the sockets' linger option based on the boolean value supplied in the value argument.  This option requires a 3rd argument of type number that indicates the timeout period (in seconds).

Returns

This method returns a reference to itself, or nil in case of an error.

ReadAtLeast

This method requests to read at least as many bytes as specified by the min argument. Once at least this amount of data is available, all available data is passed to the OnRead callback. This API should not be invoked during OnDriverInit.

Available in 1.6.0

Signature

C4:ReadAtLeast(min)

Parameters Description
num Number and must be greater than 0 and is currently limited to 1024 kb

Returns

This method returns a reference to itself, or nil in case of an error.

ReadUntil

This method requests to read data until a specific condition is met. This API should not be invoked during OnDriverInit.

Available in 1.6.0

Signature

C4:ReadUntil(arg) 

Parameters Description
arg arg can be a string, in which case the read request will be satisfied until this string was read from the socket.  arg can also be a function, which can arbitrarily decide at what point the read request is satisfied:
arg (str) All data until (and including) the value of this argument will be passed to the OnRead() callback.
arg (function) The supplied function should have the following signature: function(data). 

Returns

Value Description
bool indicates whether the matching condition to satisfy the read request was fulfilled
num bytes that should be removed from the front of the read buffer, regardless of whether the condition is fulfilled. You should return a value if you returned true as first return value, otherwise the entire data will be discarded.
The third return value is optional, and if not nil, will be used to replace the data argument of the OnRead callback handler.  This is useful if the matching process is already rather expensive (e.g. parsing an XML document), as it allows you to transfer that information directly to the OnRead() callback handler without having to do the same work again.

ReadUntilOneOf

This method requests to read data until (and including) one of the bytes in the str argument is encountered. This API should not be invoked during OnDriverInit.

Available in 1.6.0

Signature

C4:ReadUntilOneOf(str)

Parameters Description
str string with all bytes that can trigger a match. This argument cannot be an empty string.

Returns

This method returns a reference to itself, or nil in case of an error.

ReadUntilOneNotOf

This method requests to read data until (and including) any byte that is not in the str argument is encountered. This API should not be invoked during OnDriverInit.

Available in 1.6.0

Signature

C4:ReadUntilOneNotOf(str)

Parameters Description
str string with all bytes that can trigger a match. This argument cannot be an empty string.

Returns

This method returns a reference to itself, or nil in case of an error.

ReadUpTo

This method requests to read any available data up to (and including) the number of bytes specified by the max argument.  Once data is available, the OnRead callback will be called with whatever data was available, but no more than the limit specified in the max argument. This API should not be invoked during OnDriverInit

Available in 1.6.0

Signature

C4:ReadUpTo(max)

Parameters Description
num max is a number and must be greater than 0 and it is currently limited to 4096 kb

Returns

This method returns a reference to itself, or nil in case of an error.

TCPServer Interface

CreateTCPServer

This class does not in any way manage or keep track of connected clients.  If you explicitly Close() the TCP server or it goes out of scope and gets cleaned up by lua's garbage collector, it does not affect any of the accepted client connections. You can keep track of connected clients by saving them into a map in the OnAccept callback, and setting up a OnDisconnect callback for the connected client connection that removes that client from that map.

Generally, the class cleans up any resources associated with it.  For example, when the object is no longer referenced, it will clean it up.  However, there are a few exceptions:  When the class is performing an asynchronous operation, e.g. a listen request, it will remain alive until the appropriate event callback function is called.  For instance, if you call the Listen() method, the class will remain alive until it either called the OnListen (and OnResolve) callback function, or the OnError callback function, even if your lua code does not have any reference to the class during that time period.  However, once the OnListen callback was called, the class gets cleaned up unless at that point your lua code somehow references this instance. This API should not be invoked during OnDriverInit.

Available in 1.6.0

Example

This is an example of a chat server that accepts a configurable number of clients and shuts the server down after a configurable number of minutes.  It manages all its client connections and shuts them down when the server is being shut down.

local server = {
       clients = {},
       clientsCnt = 0,
       --socket = nil,
       notifyOthers = function(self, client, message)
              for cli,info in pairs(self.clients) do
                     if (cli ~= client and info.name ~= nil) then
                           cli:Write(message .. "\r\n")
                     end
              end
       end,
       broadcast = function(self, client, message)
              local info = self.clients[client]
              print("broadcast for client " .. tostring(client) .. " info: " ..tostring(info))
              if (info ~= nil and info.name ~= nil) then
                     self:notifyOthers(client, info.name .. " wrote: " .. message .. "\r\n")
                     client:Write("You wrote: " .. message .. "\r\n")
              end
       end,
       haveName = function(self, name)
              for _,info in pairs(self.clients) do
                     if (info.name ~= nil and string.lower(info.name) == string.lower(name)) then
                           return true
                     end
              end
              return false
       end,
       stripControlCharacters = function(self, data)
              local ret = ""
              for i in string.gmatch(data, "%C+") do
                     ret = ret .. i
              end
              return ret
       end,
       stop = function(self)
              if (self.socket ~= nil) then
                     self.socket:Close()
                     self.socket = nil

-- Make a copy of all clients and reset the map. -- This ensures that calls to self:broadcast() and self:notifyOthers() -- during the shutdown process get ignored. All we want the clients to -- see is the shutdown message. local clients = self.clients self.clients = {} self.clientsCnt = 0

for cli,info in pairs(clients) do print("Disconnecting " .. cli:GetRemoteAddress().ip .. ":" .. cli:GetRemoteAddress().port .. ": name: " .. tostring(info.name)) cli:Write("Server is shutting down!\r\n"):Close(true) end end end, start = function(self, maxClients, bindAddr, port, done) local calledDone = false self.socket = C4:CreateTCPServer() :OnResolve( function(srv, endpoints)

print("Server " .. tostring(srv) .. " resolved listening address") for i = 1, #endpoints do print("Available endpoints: [" .. i .. "] ip=" .. endpoints[i].ip .. ":" .. endpoints[i].port) end end ) :OnListen( function(srv, endpoint) -- Handling this callback is optional. It merely lets you know that the server is now actually listening. local addr = srv:GetLocalAddress() print("Server " .. tostring(srv) .. " chose endpoint " .. endpoint.ip .. ":" .. endpoint.port .. ", listening on " .. addr.ip .. ":" .. addr.port) if (not calledDone) then calledDone = true done(true, addr) end end ) :OnError( function(srv, code, msg, op) -- code is the system error code (as a number) -- msg is the error message as a string print("Server " .. tostring(srv) .. " Error " .. code .. " (" .. msg .. ")") if (not calledDone) then calledDone = true done(false, msg) end end ) :OnAccept( function(srv, client) -- srv is the instance C4:CreateTCPServer() returned -- client is a C4LuaTcpClient instance of the new connection that was just accepted print("Connection on server " .. tostring(srv) .. " accepted, client: " .. tostring(client)) if (self.clientsCnt >= maxClients) then client:Write("Sorry, I only allow " .. maxClients .. " concurrent connections!\r\n"):Close(true) return end local info = {} self.clients[client] = info self.clientsCnt = self.clientsCnt + 1 client :OnRead( function(cli, data) -- cli is the C4LuaTcpClient instance (same as client in the OnAccept handler) that the data was read on if (string.sub(data, -2) == "\r\n") then -- Need to check if the delimiter exists. It may not if the client sent data without one and then disconnected! data = string.sub(data, 1, -3) -- Cut off \r\n end data = self:stripControlCharacters(data) if (info.name == nil) then if (#data > 0) then if (self:haveName(data)) then cli:Write("Choose a different name, please:\r\n") else info.name = data self:notifyOthers(cli, info.name .. " joined!\r\n") cli:Write("Thank you, " .. info.name .. "! Type 'quit' to disconnect.\r\n") end else cli:Write("Please enter your name:\r\n") end cli:ReadUntil("\r\n") elseif (data == "quit") then cli:Write("Goodbye, " .. info.name .. "!\r\n"):Close(true) else if (#data > 0) then self:broadcast(cli, data) end cli:ReadUntil("\r\n") end end ) :OnWrite( function(cli) -- cli is the C4LuaTcpClient instance (same as client in the OnAccept handler). This callback is called when -- all data was sent. print("Server " .. tostring(srv) .. " Client " .. tostring(client) .. " Data was sent.") end ) :OnDisconnect( function(cli, errCode, errMsg) -- cli is the C4LuaTcpClient instance (same as client in the OnAccept handler) that the data was read on -- errCode is the system error code (as a number). On a graceful disconnect, this value is 0. -- errMsg is the error message as a string. if (errCode == 0) then print("Server " .. tostring(srv) .. " Client " .. tostring(client) .. " Disconnected gracefully.") else print("Server " .. tostring(srv) .. " Client " .. tostring(client) .. " Disconnected with error " .. errCode .. " (" .. errMsg .. ")") end

if (info.name ~= nil) then self:notifyOthers(cli, info.name .. " disconnected!\r\n") end self.clients[cli] = nil self.clientsCnt = self.clientsCnt - 1 end ) :OnError( function(cli, code, msg, op) -- cli is the C4LuaTcpClient instance (same as client in the OnAccept handler) that the data was read on -- code is the system error code (as a number) -- msg is the error message as a string -- op indicates what type of operation failed: "read", "write" print("Server " .. tostring(srv) .. " Client " .. tostring(client) .. " Error " .. code .. " (" .. msg .. ") on " .. op) end ) :Write("Welcome! Please enter your name:\r\n") :ReadUntil("\r\n") end ) :Listen(bindAddr, port) if (self.socket ~= nil) then return self end end }

-- Start the server with a limit of 5 concurrent connections, listen on all interfaces on a randomly available port. The server will shut down after 10 minutes. server:start(5, "", 0, function(success, info) if (success) then local minutes = 10 print("Server listening on " .. info.ip .. ":" .. info.port .. ". Will stop in " .. minutes .. " minutes!") C4:SetTimer(minutes 60 * 1000, function() print("Stopping server and disconnecting clients now.") server:stop() end) else print("Could not start server: " .. info) end end)

Close

This method stops the server socket, or cancels pending resolve or endpoint selection.  If a pending resolve or endpoint selection was canceled, the OnError handler will be called.  However, if the server is already accepting connections, the OnError handler will NOT be called and the server simply ceases to accept further connection requests.  Note that the server does not manage accepted client connections and will not close any of these connections. it it is up to your implementation to manage client connections and how to act when you stop the TCP server.

Available in 1.6.0

Signature

C4: Close()

Parameters

None

Returns

This method returns a reference to itself, or nil in case of an error.

GetLocalAddress

This method returns a table with the IP address and port that the server is listening on. 

Available in 1.6.0

Signature

C4:GetLocalAddress()

Parameters

None

Returns

Value Description
table IP address that the server is listening on
port number that the server is listening on

Listen

This method starts a listen request to listen on a particular host/service.  Once the host/service has been resolved and an endpoint has been chosen, the OnListen callback function will be called. This indicates that the server is now ready to accept incoming connections.  If errors occur, the OnError callback function will be called instead. This API should not be invoked during OnDriverInit.

Available in 1.6.0

Signature

C4:Listen(host, service[, backlog])

Parameters Description
host IP address or host name to listen on.  It can also be one of these special values: “*", "!all", or "!any”
”!local" or "!loopback" Listens on the loopback device
service port number or a string with the service (e.g. 80 or "http").  If this argument is 0, a random available port will be
chosen.
backlog number indicating the size of the connection accept backlog. This argument is optional

Returns

This method returns a reference to itself, or nil in case of an error.

OnAccept

This method sets a callback method that will be called whenever a new client connection has been accepted by the TCP server.

Available in 1.6.0

Signature

C4:OnAccept(func)

Parameters Description
func should have this function signature: function(server, client)
server server is this C4LuaTCPServer instance
client server is this C4LuaTCPServer instance

Returns

This method returns a reference to itself.

OnError

This method sets a callback method that will be called when an error occurs during an asynchronous operation.

Available in 1.6.0

Signature

C4:OnError(func)

Parameters Description
func should have this function signature: function(server, code, msg)
code number with the system error code
msg string with a description of the error

Returns

This method returns a reference to itself.

OnListen

This method sets a callback method that will be called once the TCP server starts listening.  This callback is called once the host/service has been resolved and the endpoints has been chosen.  It is optional to implement this callback method.

Available in 1.6.0

Signature

C4:OnListen(func)

Parameters Description
func should have this function signature: function (server, endpoint)
server This C4LuaTCPServer instance
endpoint Table with the following fields indicating the endpoint the server is listening on:
ip (string)
port (number) The port number the server is listening on

Returns

This method returns a reference to itself.

OnResolve

This method sets a callback method that will be called once the host/service has been resolved.  If implemented, it allows you to choose a particular endpoint to listen on, or to cancel the listen request.

Available in 1.6.0

Signature

C4: OnResolve(func)

Parameters Description
func should have this function signature: function (server, endpoints, choose)
server This C4LuaTCPServer instance
endpoints Array of tables describing all endpoints that the host/service could be resolved to. Each entry has the following:
ip (string) The IP address the server is listening on
port (number) The port number the server is listening on

Note that choose is a completion function with this signature: function(index) Using this closure is optional and can be used to delay making a choice.  The index argument is of type number, and it is optional.  If not provided, default behavior is requested (first endpoint, if available).  If the index argument is provided, it should be an index into the endpoints array.  If the index argument is 0, the listen request will be canceled and the OnError callback will be called with an invalid argument error (code 22).

Returns

This method returns a reference to itself.

Option

This method sets a socket option.

Available in 1.6.0

Signature

C4:Option(name, value[, ...])

Parameters Description
name string specifying the option to set. It can be one of the following:
”reuseaddr" Enables or disables the socket's reuse address option based on the boolean value supplied in the value argument.
”linger": Enables or disables the sockets' linger option based on the boolean value supplied in the value argument.  This option requires a 3rd argument of type number that indicates the timeout period (in seconds).

Returns

This method returns a reference to itself.

Media Management - Albums Interface

Overview

The examples used in the Albums section of this document will reference the following albums:

mediaId1 = C4:MediaAddAlbumInfo("http://127.0.0.1/music/Album1", "Funky Music", Album1)

songLocation1="http://127.0.0.1/music/song1.mp3"
songLocation2="http://127.0.0.1/music/song2.mp3"
songLocation3="http://127.0.0.1/music/song3.mp3"

SomeSong1 = {
--required fields
="Title Test Song Number 1",
location=songLocation1,
track_no="6",
--optional fields
name = "Name Test Song Number 1",
artist = "C4 Music Factory",
record_label="Island",
release_date="15 Jun 2004",
}

SomeSong2 = {
title="Test Song Number 2",
location=songLocation2,
track_no="1",
name = "Name Test Song Number 2",
artist = "C4 Music Factory",
record_label="Dos Record Label",
release_date="15 Jun 2222",
}

SomeSong3 = {
title="Test Song Number 3",
track_no="7",
location=songLocation3,
name = "Name Test Song Number 3",
artist = "C4 Music Factory",
record_label="Boat",
release_date="3 Dec 2002",
}

Album1 = {
artist = "Jimmy Joe",
description = "Worst episode ever",
genre = "Blues & Browns",
release_date = "1992",
release_label = "Grass and Cash",
songs = {SomeSong1, SomeSong2, SomeSong3}, 
}

MediaAddAlbumInfo

This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:MediaAddAlbumInfo ()

Parameters Description
str location
str title
table Songs information is required. Table must contain the songs you want added to the album.
data Data from MediaGetSongInfo: required fields are: title, location, track_no unique for that table

Returns

Value Description
num The new Media ID for the movie

Example

mediaId = C4:MediaAddAlbumInfo("http://127.0.0.1/music/Album1", "Funky Music", Album1)

MediaGetAlbumInfo

This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4: MediaGetAlbumInfo

Parameters Description
num This is the Media ID of the album.

Returns

Value Description
str location
str title
table Table information. The table may have entries for:
artist
record label
release date
description
genre
cover_art – this is a base64 encoded JPEG file of the cover art.
songs – an array of songs. Each song is a table, and must contain entries for
name
track number
location

Example

MyAlbumInfo= C4:MediaGetAlbumInfo(mediaId1)
print(MyAlbumInfo["name"])

MediaGetAlbumLocation

This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4: MediaGetAlbumLocations() 

Parameters Description
num The Media ID of the album.

Returns

Value Description
str The location of this media as stored in the database.

Example

print(C4:MediaGetAlbumLocation(mediaId1)) 

MediaGetAllAlbums

This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:MediaGetAllAlbums() 

Parameters

None

Returns

Value Description
Table Table containing Media IDs and locations.

Example

Example
allAlbums = C4:MediaGetAllAlbums()
for key,value in pairs(allAlbums) do
print("mediaId is "..key.. " location is "..value)
end

MediaRemoveAlbum

This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:MediaRemoveAlbum() 

Parameters Description
num The Media ID of the album. Note, all songs associated with this album will be removed as well.

Returns

None

Example

C4:MediaRemoveAlbum(mediaId1)

MediaRemoveAllAlbums

This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4: MediaRemoveAllAlbums() 

Parameter

None

Returns

None

Example

C4:MediaRemoveAllAlbums()

MediaModifyAlbumInfo

This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:MediaModifyAlbumInfo() 

Parameters Description
num media ID
str location
str name
table Song information is required. Table must contain the songs you want added to the album.
Song Table info: data from MediaGetSongInfo. Required fields are title, location and track number unique for that table.

Returns

None

Usage Note

Usage Note:A modify call does not change the media’s ID number where a delete or add call will. Modify calls are useful if programming relies on the current Media ID. For example, if a button push is programmed to play the media, and a modify call is used, the media’s current ID is maintained and programming is not impacted.

Example

C4:MediaModifyAlbumInfo(mediaId1,"http://127.0.0.1/music/Album1M
"Modified","Some New Name", Album1)

Media Management - Broadcast Video Interface

MediaAddBroadcastVideoInfo

This function is used to add a new broadcast video station media entry. This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:MediaAddBroadcastVideoInfo()

Parameters Description
str location
str title
table The table will have key of the media id and the stations locations as the values

Returns

Value Description
num The new Media ID for the station

Example

mediaId1 = C4:MediaAddBroadcastVideoInfo("https://kutv.com/watch,"KUTV",bcVideoKUTV)

MediaGetAllBroadcastVideo

This function is used to retrieve all the broadcast video stations associated with this device. This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:MediaGetAllBroadcastVideo() 

Parameters

None

Returns

Values Description
Table Table containing Media IDs and the stations locations as the values.

Example

local stations = C4:MediaGetAllBroadcastVideo()
  for mediId,loc in pairs(stations) do
    print("id " .. mediId .. " location " .. loc)
end

MediaGetBroadcastVideoInfo

This function is used to get information about an existing broadcast audio media entry. This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:MediaGetBroadcastVideoInfo() 

Parameters Description
num media ID of the station
str location
str name

Returns

Value Description
str location
str genre
str description
str name
str image. this is a base64 encoded JPEG file of the cover art.

Example

myStationInfo = C4:MediaGetBroadcastVideoInfo(mediaId1)
print(myStationInfo[name])

MediaModifyBroadcastVideoInfo

Modifies a broadcast video channel. This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:MediaModifyBroadcastVideoInfo() 

Parameters Description
str location
str name
table The table will have key of location, name, description and genre of the broadcast video channel modifications.

Returns

None

Usage Note

A modify call does not change the media’s ID number where a delete or add call will. Modify calls are useful if programming relies on the current Media ID. For example, if a button push has is programmed to play the media, and a modify call is used, the media’s current ID is maintained and programming is not impacted.

MediaRemoveBroadcastVideo

This function is used to remove a video station from the system. This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:MediaRemoveBroadcastVideo() 

Parameters Description
num The Media ID of the station to remove.

Returns

None

Example

C4:MediaRemoveBroadcastVideo(mediaId1)

Media Management - Generic Interface

MediaGetDeviceContext

Function that returns the what the device context is currently set to.  If “0” then all media APIs are using the current driver’s device id. This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:MediaGetDeviceContext)

Parameters

None

Returns

Value Description
num Driver Device ID

Example


local contextId = C4:MediaGetDeviceContext()
print("context is: " .. contextId)

prints: context is: 391

MediaRemoveAllMedia

Removes all albums songs and movies from the device. This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:MediaRemoveAllMedia)

Parameters

None

MediaSetDeviceContext

Function that sets a device id to be used for media related call.  If set to any value other than “0” then adding, modifying, retrieving or removing functionality will use the supplied device id. Note that this API must be called in the OnDriverLateInit area of the device driver.

Available from 1.6.0

Signature

C4:MediaSetDeviceContext()

Parameters Description
num New device id to be associated with media related api’s. 

Usage Note

If the number parameter is set to “0” then the media related APIs will use the current driver’s device id.

Media Management - Miscellaneous Interface

Receiver with Onscreen Binding

To enable a receiver to be capable of being the onscreen device, add the following to your <connections> section of your driver. This will then allow the room's onscreen input to be hooked up to the receiver’s output. Note that for the sections to be valid, a video path must also exist (the room must also be able to select the receiver as the video endpoint).

Example

<connection>
    <id>7500</id>
    <facing>6</facing>
    <connectionname>OnscreenNavigator</connectionname>
    <type>7</type>
    <consumer>False</consumer>
    <audiosource>False</audiosource>
    <videosource>False</videosource>
    <linelevel>False</linelevel>
   <classes>
    <class>
      <classname>ONSCREEN_SELECTION</classname>
    </class>
  </classes>
</connection>

Sending Room Keypress Commands from Receiver Driver

</span><span class="n">roomId</span> <span class="o">=</span> <span class="n">C4</span><span class="p">:</span><span class="n">RoomGetId</span><span class="p">()</span><span class="err">
    </span><span class="n">tParams</span> <span class="o">=</span> <span class="p">{}</span><span class="err">
    </span><span class="n">tParams</span> <span class="o">=</span> <span class="p">{}</span><span class="err">
</span><span class="c1">-- send 1 keypress to the room’s currently selected device</span>
</code></pre></div>
<p>Note that commands not recognized by the room and director will still be sent through to the selected proxy device. The proxy may filter out unknown commands or it may still forward them to the protocol driver.</p>
<div class="highlight"><pre class="highlight lua tab-lua"><code><span class="err">roomId = C4:RoomGetId()
</span><span class="n">tParams</span> <span class="o">=</span> <span class="p">{}</span>
<span class="err">-- send 1 keypress to the room’s currently selected device
</span><span class="n">C4</span><span class="p">:</span><span class="n">SendToDevice</span><span class="p">(</span><span class="n">roomId</span><span class="p">,</span> <span class="s2">"FOO"</span><span class="p">,</span> <span class="n">tParams</span><span class="p">)</span> <span class="err">

Output from Media Player driver when receiver driver sent above commands:

</span><span class="n">ReceivedFromProxy</span> <span class="n">called</span> <span class="k">for</span> <span class="n">mediaplayer</span> <span class="n">xbmc</span> <span class="n">with</span> <span class="n">command</span><span class="p">:</span><span class="n">PAUSE</span><span class="err">
</span><span class="o">..</span><span class="n">Parameter</span><span class="p">:</span> <span class="n">ROOM</span><span class="err">\</span><span class="n">_ID</span> <span class="n">with</span> <span class="n">value</span><span class="p">:</span> <span class="mi">39</span>
<span class="err">Received Action Response action id=12 erroCode=0
</span><span class="n">position</span><span class="o">=</span> <span class="mi">0</span> <span class="n">value</span><span class="o">=</span><span class="mi">0</span>
<span class="err">ReceivedFromProxy called for mediaplayer xbmc with command:FOO
`..Parameter: ROOM</span>_ID with value: 39

Media Management - Movies Interface

Overview

The examples used in the Movies section of this document will reference the following movie:


shrekMovie = {
  directors = "Andrew Adamson; Vicky Jenson",
  description = "In this fully computer-animated fantasy",
  cast = "Mike Myers; Eddie Murphy; John Lithgow",
  rating = "",
  genre = "Children's/Family",
  release_date = "2001",
  release_company = "DreamWorks",
  cover_art = "/9j/4AAQSkZJRgABAQEBLAEsAAD/"
}

MediaAddMovieInfo

This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:MediaAddMovieInfo ()

Parameters Description
str location
str title
table Table information. The table may have entries for:
string location
string title
string directors – comma separated
string description
string cast – comma separated
string rating
string rating reason
string reviews
string genre
string aspect ratio
string release date
string release company
string length – time span in minutes
string cover art – this is a base64 encoded JPEG file of the cover art.

Returns

Values Description
num The new Media ID for the movie

Example

`mediaId1 = C4:MediaAddMovieInfo("http://127.0.0.1/movies/shrek1", "shrek1", shrekMovie)`

MediaGetAllMovies

This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:MediaGetAllMovies()

Parameters

None

Returns

Value Description
Table Table containing Media IDs and locations.

Example

allMovies = C4:MediaGetAllMovies()
for key,value in pairs(allMovies) do
   print("mediaId is "..key.. " location is "..value)
end

MediaGetMovieInfo

This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:MediaGetMovieInfo()

Parameters Description
num This is the Media ID of the movie.
table Table information. The table may have entries for:
string location
string title
string directors – comma separated
string description
string cast – comma separated
string rating
string rating reason
string reviews
string genre
string aspect ratio
string release date
string release company
string length – time span in minutes
string cover art – this is a base64 encoded JPEG file of the cover art.

Returns

None

Example

myMovieInfo = C4:MediaGetMovieInfo(mediaId1)
print(myMovieInfo[title])

MediaGetMovieLocation

This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4: MediaGetMovieLocations()

Parameters Description
num The Media ID of the movie.

Returns

Value Description
str The location of this media as stored in the database.

Example

myLocation = C4:MediaGetMovieLocation(mediaId1)

MediaRemoveMovie

This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:MediaRemoveMovie()

Parameters Description
num The Media ID of the movie.

Returns

None

Example

C4:MediaRemoveMovie(mediaId3)

MediaRemoveAllMovies

This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4: MediaRemoveAllMovies()

Parameter

None

Returns

None

Example

C4:MediaRemoveAllMovies()

MediaModifyMovieInfo

This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:MediaModifyMovieInfo()

Parameters Description
num media ID
str location
str name
table Table information. The table may have entries for:
string location
string title
string directors – comma separated
string description
string cast – comma separated
string rating
string rating reason
string reviews
string genre
string aspect ratio
string release date
string release company
string length – time span in minutes
string cover art – this is a base64 encoded JPEG file of the cover art.

Returns

None

Usage Note

A modify call does not change the media’s ID number where a delete or add call will. Modify calls are useful if programming relies on the current Media ID. For example, if a button push has is programmed to play the media, and a modify call is used, the media’s current ID is maintained and programming is not impacted.

Example

C4:MediaModifyMovieInfo(mediaId1,"http://127.0.0.1/movies/shrek1Modified","shrek1",shrekMovie)

Media Management - Songs Interface

MediaAddSongInfo

This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:MediaAddSongInfo()

Parameters

None

Returns

Value Description
table Information for location and title.

Example

mySongInfo = C4:MediaGetSongInfo(mediaId1)
print(mySongInfo["name"])

MediaGetSongLocation

This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4: MediaGetSongLocation( 

Parameters Description
num The Media ID of the song.

Returns

Value Description
str The location of this media as stored in the database.

Example

print(C4:MediaGetSongLocation(mediaId1))

MediaRemoveSong

This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:MediaRemoveSong()

Parameters Description
num The Media ID of the song.

Returns

None

Example

C4:MediaRemoveSong(mediaId1)

MediaLinkSongToAlbum

This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:MediaLinkSongToAlbum() 

Parameters Description
num The Media ID of the album
num The Media ID of the song
num Track-based sequence that this song belongs within the album

Returns

None

Example

C4:MediaLinkSongToAlbum(mediaIdAlbum, mediaIdSong, 1)

MediaGetSongsforAlbum

This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:MediaGetSongsforAlbum() 

Parameters Description
num The Media ID of the album containing songs

Returns

Value Description
table Values including Media ID and location for each song.

Example


AllSongs= C4:MediaGetSongsForAlbum(mediaIdAlbum)
for key,value in pairs(AllSongs) do
print("mediaId is "..key.. " location is "..value)
end

MediaModifySongInfo

This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:MediaModifySongInfo() 

Parameters Description
num media ID
str location
str name

Returns

None

Usage Note

A modify call does not change the media’s ID number where a delete or add call will. Modify calls are useful if programming relies on the current Media ID. For example, if a button push is programmed to play the media, and a modify call is used, the media’s current ID is maintained and programming is not impacted.

Example

C4:MediaModifySongInfo(mediaId1, "http://127.0.0.1/music/songtest", "Test of modified song")

Miscellaneous Interface

AddDynamicBinding

Function called by a DriverWorks driver to add a dynamic binding (a binding added at runtime). This is typically done by security panels or other devices whose number of bindings are unknown when the driver is created.

Available from 1.6.0

Signature

C4:AddDynamicBinding(idBinding, strType, bIsProvider, strName, strClass, bHidden, bAutoBind)

Parameters Description
num ID of the dynamic binding.
str Type of dynamic binding. Valid types include: CONTROL, PROXY
bool Provider: Whether the binding is a Provider or a Consumer binding.
str Name of binding that will appear in Composer’s connections page.
str Class of dynamic binding that is being created.
bool Hidden: Whether the dynamic binding is hidden. Should typically be false.
bool AutoBind: Whether the dynamic binding should be auto-bound. Should typically be false

Example

Dynamically create 4 Zone Contact Bindings for a Security Driver:

C4:AddDynamicBinding(101, "CONTROL", true, "Zone 1", "CONTACT_SENSOR", false, false)
C4:AddDynamicBinding(102, "CONTROL", true, "Zone 2", "CONTACT_SENSOR", false, false)
C4:AddDynamicBinding(103, "CONTROL", true, "Zone 3", "CONTACT_SENSOR", false, false)

Usage Note

Currently, the AddDynamicBinding API does not work for Audio, Video and Room Control bindings.

It is the responsibility of the DriverWorks driver to maintain the Dynamic bindings and to restore them from persistent data upon the driver being initialized. If this is not done, the bindings will not be available after a Director restart.

If dynamic bindings have been connected in Composer, if they are properly restored by the DriverWorks driver, the connections made between the bindings will be automatically restored.

To the right is an example of how to create and save bindings for three security contacts:


  PersistData = {`}
end

PersistData["zonebindings"] = {}
PersistData["zonebindings"][101] = "Zone 1"

C4:AddDynamicBinding(101, "CONTROL", true, "Zone 1", "CONTACT_SENSOR", false, false)
PersistData["zonebindings"][102] = "Zone 2"

C4:AddDynamicBinding(102, "CONTROL", true, "Zone 2", "CONTACT_SENSOR", false, false)
PersistData["zonebindings"][103] = "Zone 3"
C4:AddDynamicBinding(103, "CONTROL", true, "Zone 3", "CONTACT_SENSOR", false, false)

The next is an example of how to restore saved bindings. This code should be in the main body of the script section of the driver, not within any declared function:

if (PersistData ~= nil) then
  for key,value in pairs(PersistData["zonebindings"]) do 
    C4:AddDynamicBinding(key, "CONTROL", true, value, "CONTACT_SENSOR", false, false)
  end
end

A sample driver using AddDyamicBinding can be found in the Samples folder of the SDK.

Warning

No events will be sent prior to OnDriverLateInit. If an Event is required this method must be invoked in OnDriverLateInit.

AllowExecute

Beginning with OS release 2.6.0, default runtime editing of encrypted drivers has been deprecated. This has been done to better protect encrypted drivers from unwanted code review or hacking. The AllowExecute API allows for the runtime editing of encrypted drivers through its setting. The API defaults to a setting of False. When set to True, the lua command window will not support entry of any data and the lua output window cannot be used as a display. Use of this API allows driver developers to build into their driver the option to enable remote execution permanently or embed the function call within your own debugging functions to allow or disallow executing of commands in Composer. This API can be invoked during OnDriverInit.

Signature

C4:AllowExecute()

Parameters Description
bool True / False

Base64Encode

Function called in a DriverWorks driver to encode the specified string as a Base64-encoded string. This API can be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:Base64Encode(strToEncode)

Parameters Description
str String to be encoded in Base64 encoding

Returns

Values Description
str String encoded in Base64 encoding.

Base64Decode

Function called in a DriverWorks driver to decode the specified string from a Base64-encoded string. This API can be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:Base64Decode(strToDecode)

Parameters Description
str String to be decoded from Base64 encoding

Returns

Value Description
str Decoded from Base64 encoding.

PersistData

The Lua Table ‘PersistData’ is available for drivers to keep persistent data across director restarts. Any values placed into the PersistData table will exist in the PersistData table when the driver is loaded after a director restart.

Note: we do not guarantee that binary data will be persisted correctly. If you wish to persist binary data in the PersistData table, it is recommended that you encode it to be 7-bit safe, by using something like C4:Base64Encode.

Available from 1.6.0

Signature

PersistData = {}

Usage Note

It is recommended to use the PersistSetValue and PersistGetValue calls if they're supported in your O.S. These calls were introduced with OS 2.10.0. They immediately write to the state database.The PersistData table only is only written out when Director cycles through each driver to save its state. Because of this, latency issues can occur when using PersistData.

Exit Navigation

This command is sent to the room to change the room from the “In Navigation” mode back to the “Normal” mode. While in the “Normal” mode, the commands sent to the room are sent to the selected audio or video device. When in the “In Navigation” mode a set of the navigational commands are sent to the on screen device.

For reference, the set of commands that are forwarded are:

Sending the “CONTROL4” command to the room will have it select the bound on screen navigation and enter the “In Navigation” mode.

Sending the EXIT_NAVIGATION command will have the room go back to the “Normal” mode.

Available from 1.6.0

Example

roomId = C4:RoomGetId() -- now tell the room to enter "In Navigation" mode tParams = {} C4:SendToDevice(roomId, "CONTROL4", tParams) -- now go back to normal mode C4:SendToDevice(roomId, "EXIT_NAVIGATION", tParams)

GetCapability

Function called from DriverWorks driver to get a capability from the driver. This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:GetCapability(strName)

Parameters Description
str The name of the capability to retrieve

Returns

Value Description
str The value of the capability retrieved from the driver file

Examples

If this device supports discrete volume control, send discrete volume, otherwise, send a Volume Up or Volume Down command:

if (C4:GetCapability("has_discrete_volume_control") == "False") then if (VolumeValue > CurVolumeValue) then SendVolumeUp() else SendVolumeDown() end else SendVolumeDiscrete(VolumeValue) End OnBindingChanged

GetDeviceData

This API returns data found in the driver's device data, <devicedata> XML. The Device ID of the driver value must be passed to return the XML content. An optional string value parameter can be passed to retrieve specific XML data.

Available from 2.10.0

Signature

C4:GetDeviceData()

Parameters Description
num Device ID of the driver.
str tagName is an optional parameter that can be passed to return specific devicedata.

Usage Note

For example, if the “string parameter is passed as “version”, the value for the devicedata's <version></version> XML tag will be returned.

Returns

XML data found in the driver's <devicedata></devicedata>.

Usage Note

If multiple instances of identical XML tags exist in the <devicedata> section for the driver, only the first instance of that XML data will be returned. Also, the GetDeviceData API only has the ability to return data from the first two levels of XML.

Examples

For example purposes, consider the following sample XML to the right. It is taken from a Pool Controller's <devicedata></devicedata>. This Pool Controller has a DeviceID of 8 in the project:

<devicedata>
    <copyright>Copyright 2016 Control4 Corporation.  All rights reserved.</copyright>
    <creator>Control4</creator>
    <created>8/26/2014 2:09 PM</created>
    <modified>11/17/2015 11:00 AM</modified>
    <version>7</version>
    <control>lua_gen</control>
    <controlmethod>ip</controlmethod>
    <driver>DriverWorks</driver>
    <proxies qty="1">
        <proxy proxybindingid="5001" primary="True">pool</proxy>
    </proxies>
    <capabilities>
        <pool_pumpmodes>Off,On</pool_pumpmodes>
        <spa_pumpmodes>Off,On</spa_pumpmodes>
        <temp_min>34</temp_min>
        <temp_max>104</temp_max>
        <pool_heat_modes>
            <mode>
                <id>1</id>
                <text>Heater</text>
            </mode>
            <mode>
                <id>2</id>
                <text>Solar Heater</text>
            </mode>
        </pool_heat_modes>
        <spa_heat_modes>
            <mode>
                <id>1</id>
                <text>Heater</text>
            </mode>
        </spa_heat_modes>
    </capabilities>
</devicedata>

If C4:GetDeviceData is executed with only the Device ID value, as:

C4:GetDeviceData(8)

All of the XML found in the <devicedata> section of the driver is returned.

C4:GetDeviceData can also be executed with the optional tagName parameter to return specific XML data. For example, If C4:GetDeviceData is executed with the Device ID value and the version tag, as:

C4:GetDeviceData(8, “version”)

The return value will be: 7

Similarly, the API can return all of the supported pump modes by passing C4:GetDeviceData as:

C4:GetDeviceData(8, “pool\_pumpmodes”) ` The return values will be: Off,On

If we wanted to return all of the pool Controller's capabilities, C4:GetDeviceData is passed as:

C4:GetDeviceData(8, “capabilities”)

To the right is the return value:

-- Return Value

<pool_pumpmodes>Off,On</pool_pumpmodes>
<spa_pumpmodes>Off,On</spa_pumpmodes>
<temp_min>34</temp_min>
<temp_max>104</temp_max>
<pool_heat_modes>
    <mode>
        <id>1</id>
        <text>Heater</text>
    </mode>
    <mode>
        <id>2</id>
        <text>Solar Heater</text>
    </mode>
</pool_heat_modes>
<spa_heat_modes>
    <mode>
        <id>1</id>
        <text>Heater</text>
    </mode>
</spa_heat_modes

GetDevices

The GetDevices API provides the ability to return a table of devices based on driver names and/or device ID values. Additionally, the use of the location parameter further limits the list returned based on locations found within a project.

Available from 2.10.0

Signature

GetDevices(tFilter, locationFilter)

Parameters

tFilter: (optional) The tFilter is a table of key/value pairs that specify the filters used within the search. The search can be filtered by .c4i or .c4z driver names and/or device id values. To filter by driver names, add an entry in the table called C4iNames. The value is a string consisting of a comma delimited list of .c4i or .c4z names such as:

control4_sr250.c4i, control4_sr150.c4i.

An example of a table would be:

tFilter = {C4iNames = "control4_sr260.c4i,control4_sr250.c4i,control4_sr150.c4i"}

To filter by device id values rather than driver names, add an entry in the table called DeviceIds. The value is a string consisting of a comma delimited list of ID values representing Proxy IDs or Device IDs such as: “22,23,24”. An example of a table would be:

tFilter = {DeviceIds = "22,34,56"}

Note that the tFilter parameter is an optional parameter of the GetDevices function. Also, empty filter tables tFilter = {} can be passed within the function. This will result in all devices being included when the function is executed.

locationFilter: The locationFilter parameter is a comma delimited list of project location IDs. Only devices matching the filter criteria used in the first parameter and belonging to one of the locations in the list will be included when the function is executed. Locations IDs include Sites, Buildings, Floors and Rooms.

Returns

Value Description
table tReturn: Varies based on not only the parameters passed in it, but the types of drivers in the project. Driver types that should be considered when viewing return data include: Combo Drivers, Proxy/Protocol Driver and Multi-Proxy Drivers.

To better understand how driver data is arranged in tables and how the data is returned by the GetDevices API, the following section consists of example data returned from the function.

Example 1

Return Example for All Drivers including Combo Drivers GetDevices returns a table with an entry for each device found. The key of the entry is the ID number of the device. The value is a table that contains additional information about the device. The table contains the following key-value pairs:

Key Value
driverFileName <driver_filename>
deviceName <device_filename>
roomID <room_ID>
roomName <room_name>

To the right is an example where you would like to get a list of all the remotes in the project. Passing driver names, you would use GetDevices in the following manner:

-- Example 1

tFilter = {
    C4iNames = "control4_sr260.c4i,
        control4_sr250.c4i, 
        control4_sr150.c4i"}

tResult = C4:GetDevices(tFilter)

The table that is returned by the GetDevices command (that was stored in tReturn) is to the right :

 -- Example 1 Return

    [27] = {
        driverFileName = "control4_sr150.c4i",
        deviceName = "System Remote Control SR-150",
        roomId = "26",
        roomName = "Master"
    },
    [17] = {
        driverFileName = "control4_sr260.c4i",
        deviceName = "System Remote Control SR260",
        roomId = "16",
        roomName = "Dining"
    },
    [21] = {
        driverFileName = "control4_sr150.c4i",
        deviceName = "System Remote Control SR-150",
        roomId = "20",
        roomName = "Laundry"
    },
    [25] = {
        driverFileName = "control4_sr250.c4i",
        deviceName = "System Remote Control SR-250",
        roomId = "24",
        roomName = "Bathroom"
    },
    [19] = {
        driverFileName = "control4_sr150.c4i",
        deviceName = "System Remote Control SR-150",
        roomId = "18",
        roomName = "Kitchen"
    },
    [14] = {
        driverFileName = "control4_sr260.c4i",
        deviceName = "System Remote Control SR260",
        roomId = "13",
        roomName = "Living"
    }
}

In this example, note the value of 27. This is the index into the table that, in this example, contains a list of key/value pairs of device information for the remote with device id of 27. Based on our return table, we can see the project has six remotes and we can also see which room those remotes are located as well as the location ID value and their respective device name.

Example 2

Return Example for a Proxy Driver Proxy Drivers return a table as described in the previous example with the addition of an extra key/value pair. The additional information is the protocol information for the driver. In the table returned, the additional key is the driverFilename and its value is the string of the protocol's name. The return table structure looks like this:

Key Value
driverFileName <driver_filename>
deviceName <device_filename>
roomID <room_ID>
roomName <room_name>

In addition to key value pairs above, a protocol sub-table is also returned that contains the protocol information. This table contains another table with the file name of the protocol and the device name: …

Protocol Table
deviceId table
driverFileName <protocol_filename> 
deviceName <name_of_devie>

For example, if you would like to get a list of all lights in the project, you could execute GetDevices passing the light_v2.c4z"as the tFilter parameter. light_v2.c4z is the proxy file name used by the lights:

C4:GetDevices(`light_v2.c4z`)

The table that is returned by the GetDevices command looks like this:

-- Example 2

{
    [11] = {
        deviceName = "Keypad Dimmer Light",
        protocol = {
            [10] = {
                driverFileName = `combo_dimmer.c4i`,
                deviceName = "Keypad Dimmer Light"
            }
        },
        roomName = "Foyer",
        roomId = "9",
        driverFileName = "light_v2.c4i"
    }
}

Based on this return table, we can see that the project has one light., located in the Foyer, which happens to have a location ID of 9. Additionally, we can see the protocol sub-table that is returned with the driver filename and the device name.

Example 3: Return Example for a Protocol Driver Protocol Drivers that have one or more proxies have an additional key-value pair returned from GetDevices. The key is proxies. "proxies" is a table with an entry for each proxy found within the driver. The key of the entry is the Proxy ID. The value is a table that contains additional information about the proxy, specifically the proxyFilename and deviceName values.

The table contains the following key-value pairs:

Key Value
driverFileName <driver_filename>
deviceName <device_filename>
roomID <room_ID>
roomName <room_name>

In addition to key value pairs above, a proxy sub-table is also returned that contains the proxy information. This table contains another table with the file name of the proxy and the device name:

Key Value
deviceId table
driverFileName <proxy_filename>
deviceName <name_of_devie>

If the device utilizes multiple proxies, each of those proxies will be represented here by its respective table.

Consider an example where you would like to get a list of all of the keypad dimmers in the project. These dimmer devices rely on two proxies: a proxy for the dimmer portion of the device light_v2 proxy as well as a proxy for the keypad capabilities keypad_proxy. To do this, you can pass the proxy id value used by the dimmers in the tFilter parameter:

tFilter = {
    c4iNames = "combo_dimmer.c4i"}

tResult = C4:GetDevices(tFilter)

The tReturn table would look like this:
{
    [10] = {
        deviceName = "Keypad Dimmer Light",
        proxies = {
            [11] = {
                driverFileName = "light_v2.c4i",
                deviceName = "Keypad Dimmer Light"
            },
            [12] = {
                driverFileName = "keypad_proxy.c4i",
                deviceName = "Keypad"
            }
        },
        roomName = "Foyer",
        roomId = "9",
        driverFileName = "combo_dimmer.c4i"
    }
}

Based on this return table, we can see to the right that the project has one light, located in the Foyer, which happens to have a location ID of 9. Additionally, we can see the two proxy sub-tables that are returned with the driver filename.

GetDevicesByName

Function used to obtain the Device ID and the Room ID assigned to a device in the project. This API should not be invoked during OnDriverInit.

Available from 2.8.0

Signature

C4:GetDeviceByName(str,str)

Parameter Description
str Name of the Device in the project.
str Optional. Name of the Room where the Device resides.

Returns

Value Description
table Device ID and Room ID values.

Usage Note

The ID value returned for the Device is actually the Proxy ID.

Example

C4:GetDevicesByName("AV Switch","Theater")

GetDeviceID

Function called from DriverWorks driver to get this driver’s Device ID. This API should not be invoked during OnDriverInit.

Signature

C4:GetDeviceID()

GetDeviceVariables

Function used to obtain a Device's variables. This API should not be invoked during OnDriverInit.

Available from 2.8.0

Signature

C4:GetDeviceVariables()

Parameter Description
num This is the Proxy ID or the Protocol ID assigned to the Device in the project.

Returns

Value Description
table Table of all of the proxy variables or protocol variables for the Device (depending on the parameter passed) as well as all of the information for each of the variables.

Example

C4:GetDeviceVariables(1000)

GetDriverConfigInfo

Function that returns the XML contents of a driver's config.xml file. This API should not be invoked during OnDriverInit.

Available from 2.8.0

Signature

C4:GetDriverConfigInfo()

Parameter Description
str XML tag for the inner XML that is being requested. This is passed in a string format without the XML brackets.

Returns

Value Description
xml XML of the tag that is passed as a parameter.

Usage Note

User defined XML tags can also be returned using this function.

Example

C4:GetDriverConfigInfo("version")

GetLocale

Function to get the current locale of the system. This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:GetLocale()

Parameters

None

Returns

String of local.

Example

print("Current locale is " .. C4:GetLocale())
 Output: Current locale is C

GetProjectHierarchy

This API returns a table. The table is a representation of the project. The table consists of key/value pairs where the key is the ID of the location. The value is a table with entries of all of the location’s children if any. It also contains the locations name and type.

Available from 2.10.0

Signature

C4:GetProjectHierarchy()

Parameter Description
str location (optional) – The location parameter can be passed to identify a specific place in the project where project hierarchy data will be returned. All children of the location specified (including itself) will be included in the results.

Returns

Value Description
table Table that represents the project hierarchy.

GetPrivateKeyPassword

This function allows Director to request the private key password from a driver. Implementing GetPrivateKeyPassword within a driver permits a password to be returned for a connection which requires client certificate. When implemented correctly (see Usage Notes below), this function should return the string value of the SSL Certificate password. When using a protected certificate it is highly recommend that the driver be encrypted as there is no protection from this function being called by an end user.

Available from 1.6.0
Parameter Description
num Binding ID of the network connection with the password-protected certificate.
num Port number for the network connection with the password-protected certificate.

Returns

Value Description
str String value of the SSL Certificate password

Usage Notes

SSL Connection Setup: An example “class” of connections that enable the declaration of an SSL connection within a driver file is defined to the right. The code example declares an SSL connection bound to port 2112.

<class>
 <classname>SSL</classname>
 <ports>
  <port>
    <number>2112</number>
    <auto_connect>true</auto_connect>
    <monitor_connection>true</monitor_connection>
    <keep_connection>true</keep_connection>
    <certificate>./cert/cert.pem</certificate>
    <private_key protected="True">./cert/key.pem</private_key>
    <cacert>./cert/cacert.pem</cacert>
    <verify_mode>peer</verify_mode>
    <method>tlsv12</method>
  </port>
 </ports>
</class>

In the driver’s XML definition, the <port></port>section in the example has numerous parameters. Several of these are required for SSL Certificate support. Those parameters are:

certificate - Path to the certificate to use for the connection. The path is relative to driver’s C4Z location. In this example, a directory at the root of the .c4z file named cert has been created that contains the SSL files.

private_key - Path to the private key to use for the connection. The path is also relative to the driver’s C4Z location and we can see in the example that the key file resides in the cert directory.

If the client cert id password protected, (attribute of True) then Director will call GetPrivateKeyPassword to retrieve the password from the driver. See the example to the right.

function GetPrivateKeyPassword(Binding, Port)
   return 'TheKey'
end

cacert - Path to the CA (certificate authority) certificate to use for the connection. As with the cert.pem and key.pem files, in our example cacert.pem resides in the created cert directory.

Note that It is not required to split the <certificate>, <private_key> and <cacert> elements out into separate driver files to work properly.  If the SSL cert files are maintained in individual driver files, their respective directory names must be passed in the connection XML.

verify_mode - Specifies the verification mode to use for the connection. The verify mode corresponds to those supported by OpenSSL. Note that Control4 currently supports only the peer verification mode SSL_VERIFY_PEER. Value values include:

If this property is omitted, then Director defaults to use no verification (“none”).

method - Specifies the method to use for establishing the connection. Valid values include:

If this property is omitted, then Director defaults to using sslv23 (which is the OpenSSL default).

.c4zproj Update: Once the SSL connection XML is correctly configured to include the driver directory that contains your SSL cert files, it will be necessary to update your driver’s c4zproj manifest XML to include the new directory. Based on the example above, the addition of the following line is required within the <Items></Items>section of the manifest :

<Item type="dir" c4zDir="cert" name="cert" recurse="true" exclude="false" />

GetProjectItems

If no parameter is passed, this API returns the entire project as an .XML string. This string can then be parsed to retrieve variable IDs. The API supports several parameters (filters) that will return specific XML. This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:GetProjectItems()

Parameter Description
str Filter. Optional, Filters can be applied to GetProjectItems(). Each filter is a separate string parameter to the function. The list of filters include: ALL, LOCATIONS, PROXIES, DEVICES, AGENTS, LIMIT_DEVICE_DATA, JUST_CAPABILITIES and NO_ROOT_TAGS

Returns

Value Description
str Project data in XML format.

Examples

To return the entire project in XML:

print(C4:GetProjectItems())

To return general information about the project i.e. location, dealer info, etc:

print(C4:GetProjectItems("LOCATIONS", "LIMIT_DEVICE_DATA","NO_ROOT_TAGS"))

GetSystemType

Function that returns the controller type used as the primary controller in a project. Returns OS Info of Windows when called from a Virtual Director environment.

Available from 2.9.0

Signature

C4:GetSystemType()

Parameter

None

Returns

None

Examples

print(C4:GetSystemType()) Output: XDT_EA5

Virtual Director Example:

print(C4:GetSystemType()) Output: XDT_Windows

GetText

Function to get a string translated into the current locale from a “C” (English) input string. This will only return translated strings if there is a corresponding input -> translation match in the current translated string for the set locale. If no translation is found the input string is returned. This API can be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:GetText()

Parameter Description
str String to be translated

Returns

Value Description
str Translated string

Example

print ("Translation of stop is " .. C4:GetText("stop"))

Output: 

Translation of stop is stop

GetUniqueMAC

Function to get the unique MAC address of the Director box. This API can be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:GetUniqueMAC()

Parameter

None

Returns

None

Usage Note

The unique MAC may not be the active MAC if multiple NICs are present. For example, for systems using a wireless interface the MAC returned will be the MAC of the wired Ethernet card. When using Virtual Director, the MAC returned will be the PC's MAC address.

Example

print("Unique mac is " .. C4:GetUniqueMAC()) Output: Unique mac is 000FFF102F73

ntoh 1

Function called from DriverWorks driver to get a capability from the driver’s .c4z file. This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:ntoh_1()

Parameter Description
str The name of the capability to retrieve

Returns

Value Description
str The value of the capability retrieved from the driver file

Example

If this device supports discrete volume control, send discrete volume, otherwise, send a Volume Up or Volume Down command:

if (C4:GetCapability("has_discrete_volume_control") == "False") then
  if (VolumeValue > CurVolumeValue) then
    SendVolumeUp()
  else
    SendVolumeDown()
  end
else
  SendVolumeDiscrete(VolumeValue)
End
OnBindingChanged

htoh 2

Converts the numeric value passed in to network byte order. This API can be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:htoh_1()

Parameter Description
int Number to be converted

Returns

Value Description
str 8 byte string representing the converted network byte order

Usage Note

This function is typically used to convert numeric values to be passed over a network, when the byte order of the two ends is unknown or may be different from each other. This way, ‘little-endian’ and ‘big-endian’ machines can communicate without confusion. ‘Host’ byte order is the byte order of values on the local machine, and ‘Network’ byte order is the standard byte order on Ethernet networks.

Example

nbo = C4:ntoh_l(0x34120000)
print("network val is " .. nbo)
Output: network val is 00001234

OnBindingChanged

Converts the numeric value passed in to network byte order. This API can be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:OnBindingChanged(idBinding, strClass, bIsBound, otherDeviceID, otherBindngID) 

Parameter Description
num ID of the binding whose state has changed
str Class of binding that has changed. A single binding can have multiple classes: COMPONENT, STEREO, etc
bool Whether the binding has been bound or unbound.
num ID value representing the device that IS NOT the Device who's Binding ID is the first parameter for this API.
otherBindingID Binding ID for the device represented by the otherDeviceID value in the parameter above.

Returns

None

Usage Note

Protocol drivers do not get OnBindingChanged notifications for AV and Room bindings being bound, only control type bindings (Serial, IR, etc.). It is intended to be used specifically for when serial bindings are made, so the driver knows it can send initialization, etc. to the now-connected device.

OnDriverDestroyed

Called when a driver is deleted from a project, updated within a project or Director is shut down. All of the driver's timers will be killed within the OnDriverDestroyed function.

Available from 1.6.0

Signature

OnDriverDestroyed(strDIT) 

Parameter Description
str This optional parameter indicates the scenario in which the driver is initializing. Scenarios include:
DIT_UPDATING: Called as a result of the driver being updated.
DIT_LOADED: Called manually after the driver has already been loaded.

The DIT parameters are available in O.S. 3.2.0 and later.

Usage Note

Driver Initialization and Destruction

When a driver is loaded, there are two initialization functions that are called if those functions exist in the driver. They are OnDriverInit and OnDriverLateInit. When a driver is being removed, updated or otherwise removed from memory, OnDriverDestroyed will be called if that function has been implemented within the driver.

Your driver will need to implement these functions in order to complete its initialization process successfully. It’s important to know when these functions are called in order to know how to properly initialize a driver.

There are multiple instances of when a driver is loaded. Driver initialization occurs under the following conditions:

Driver Added to Project

When a driver is added to a project, OnDriverInit will be called followed by a call to OnDriverLateInit.

Project Load 

When a project is loaded, either when director starts up or a new project is loaded, the following occurs:

  1. As each driver is loaded, the OnDriverInit function is called.
  2. After all the drivers in the project have been loaded, then OnDriverLateInit is called for all the drivers in the project. This ensures that all the driver’s bindings and initialization is complete. Any initialization that requires that all the bindings be bound, or other driver initialization is complete should be done in OnDriverLateInit.

Driver Update

When a driver is being updated, prior to the driver being reloaded, OnDriverDestroyed will be called. This will allow the driver to do any necessary cleanup prior to the driver being reloaded. When the driver is reloaded, OnDriverInit will be called followed by a call to OnDriverLateInit.

There may be instances when a driver needs to know under what condition or event caused the Initialization or Destroyed functions to be called. OS Release 3.2.0 introduced a new string parameter to these functions to identify the reason for the call. This parameter, driverInitType (DIT) provides this information.

OnDriverInit and OnDriverLateInit valid values for this parameter are as follows:

DIT_ADDING: When a driver is being added.

DIT_STARTUP: When a project is being loaded.

DIT_UPDATING: When a driver is being updated.

OnDriverDestroyed valid values are as follows:

DIT_LOADED: When the driver is being removed or director is being shut down.

DIT_UPDATING: When a driver is being updated.

Example

-- Release things this driver had allocated...

function OnDriverDestroyed()
    if (driverInitType == "DIT_UPDATING") then
        -- Invoked prior to a driver being updated
    elseif (driverInitType == "DIT_ LOADED") then
        -- Invoked prior to the driver being unloaded or
        -- removed from a project.
    end
end

OnDriverInit

Function invoked when a driver is loaded or being updated. This API is provided for the driver developer to initialize all of the driver objects that require initialization.

Available from 2.0.0

Signature

OnDriverInit(strDIT) 

Parameter Description
str This optional parameter indicates the scenario in which the driver is initializing. Scenarios include:
DIT_ADDING: Called as a result of the driver being added to a project.
DIT_STARTUP: Called as a result of Director starting or a new project being loaded.
DIT_UPDATING: Called as a result of the driver being updated.

The DIT parameters are available in O.S. 3.2.0 and later.

Usage Note

Driver Initialization and Destruction

When a driver is loaded, there are two initialization functions that are called if those functions exist in the driver. They are OnDriverInit and OnDriverLateInit. When a driver is being removed, updated or otherwise removed from memory, OnDriverDestroyed will be called if that function has been implemented within the driver.

Your driver will need to implement these functions in order to complete its initialization process successfully. It’s important to know when these functions are called in order to know how to properly initialize a driver.

There are multiple instances of when a driver is loaded. Driver initialization occurs under the following conditions:

Driver Added to Project

When a driver is added to a project, OnDriverInit will be called followed by a call to OnDriverLateInit.

Project Load 

When a project is loaded, either when director starts up or a new project is loaded, the following occurs: 1. As each driver is loaded, the OnDriverInit function is called. 2. After all the drivers in the project have been loaded, then OnDriverLateInit is called for all the drivers in the project. This ensures that all the driver’s bindings and initialization is complete. Any initialization that requires that all the bindings be bound, or other driver initialization is complete should be done in OnDriverLateInit.

Driver Update

When a driver is being updated, prior to the driver being reloaded, OnDriverDestroyed will be called. This will allow the driver to do any necessary cleanup prior to the driver being reloaded. When the driver is reloaded, OnDriverInit will be called followed by a call to OnDriverLateInit.

There may be instances when a driver needs to know under what condition or event caused the Initialization or Destroyed functions to be called. OS Release 3.2.0 introduced a new string parameter to these functions to identify the reason for the call. This parameter, driverInitType (DIT) provides this information.

OnDriverInit and OnDriverLateInit valid values for this parameter are as follows:

OnDriverDestroyed valid values are as follows:

Example

function OnDriverInit(driverInitType)

    -- Fire On Property Changed to set the initial Headers and other
    -- Property global sets, they'll change if Property is changed.
    for k,v in pairs(Properties) do
       OnPropertyChanged(k)
    end

    C4:AddVariable("LIGHT_LEVEL", "0", "INT")
    C4:AddVariable("FIRMWARE_VERSION", "", "STRING")
    C4:AddVariable("EMERGENCY_MODE", "", "BOOL")

    if (driverInitType == "DIT_ADDING") then
        -- Initialization needed only when the driver is added
        -- to a project
    elseif (driverInitType == "DIT_STARTUP") then
        -- Initialization needed only during initial startup
    elseif (driverInitType == "DIT_UPDATING") then
        -- Initialization needed only after a driver update
    end
end

OnDriverLateInit

Function that serves as a callback into a project after the project is loaded. If any initialization has to occur after the project is loaded, it must occur in OndriverLateInit. See the safe usage table for a list of APIs that can be invoked before OnDriverLateInit is executed.

Available from 2.5.0

Signature

OnDriverLateInit(strDIT) 

Parameter Description
str This optional parameter indicates the scenario in which the driver is initializing. Scenarios include:
DIT_ADDING: Called as a result of the driver being added to a project.
DIT_STARTUP: Called as a result of Director starting or a new project being loaded.
DIT_UPDATING: Called as a result of the driver being updated.

The DIT parameters are available in O.S. 3.2.0 and later.

Usage Note

Driver Initialization and Destruction When a driver is loaded, there are two initialization functions that are called if those functions exist in the driver. They are OnDriverInit and OnDriverLateInit. When a driver is being removed, updated or otherwise removed from memory, OnDriverDestroyed will be called if that function has been implemented within the driver.

Your driver will need to implement these functions in order to complete its initialization process successfully. It’s important to know when these functions are called in order to know how to properly initialize a driver.

There are multiple instances of when a driver is loaded. Driver initialization occurs under the following conditions:

Driver Added to Project

When a driver is added to a project, OnDriverInit will be called followed by a call to OnDriverLateInit.

Project Load 

When a project is loaded, either when director starts up or a new project is loaded, the following occurs: 1. As each driver is loaded, the OnDriverInit function is called. 2. After all the drivers in the project have been loaded, then OnDriverLateInit is called for all the drivers in the project. This ensures that all the driver’s bindings and initialization is complete. Any initialization that requires that all the bindings be bound, or other driver initialization is complete should be done in OnDriverLateInit.

Driver Update

When a driver is being updated and prior to the driver being reloaded, OnDriverDestroyed will be called. This will allow the driver to do any necessary cleanup prior to the driver being reloaded. When the driver is reloaded, OnDriverInit will be called followed by a call to OnDriverLateInit.

There may be instances when a driver needs to know under what condition or event caused the Initialization or Destroyed functions to be called. OS Release 3.2.0 introduced a new string parameter to these functions to identify the reason for the call. This parameter, driverInitType (DIT) provides this information.

OnDriverInit and OnDriverLateInit valid values for this parameter are as follows:

OnDriverDestroyed valid values are as follows:

Example

function OnDriverLateInit(driverInitType)

    if (driverInitType == "DIT_ADDING") then
        -- Initialization needed only when the driver is added
        -- to a project
    elseif (driverInitType == "DIT_STARTUP") then
        -- Initialization needed only during initial startup
    elseif (driverInitType == "DIT_UPDATING") then
        -- Initialization needed only after a driver update
    end

-- Release things this driver had allocated...
function OnDriverDestroyed()
end

Safe Usage of OnDriverInit and OnDriverLateInit

As best practice, Control4 recommends invoking certain API functions prior to OnDriverLateInit. The table below identifies functions that can safely be invoked during driver initialization through OnDriverInit with a designation of "YES". Some API functions have significant performance impacts to Director during startup or have been proven to produce non-deterministic results when invoked in OndriverInit. The APIs are identified in the table below with a designation of "NO".

API Invoke Before OnDriverLateInit  Notes
AddDynamicBinding Warning No Events will be sent prior to OnDriverlateInit. If an Event is required, this must be invoked in OnDriverLateInit
AddEvent NO
AddTimer NO
AddVariable YES Note that Variables need to be added in OnDriverInit. Programming attached to variables added after OnDriverInit may not work properly on Director restart.
AllowExecute YES
Attach NO
Base64Decode YES
Base64Encode YES
blowfishEcbdecrypt YES
blowfishECbEncrypt YES
CallAsynch NO
CheckLicense NO
Close NO
Connect NO
CreateNetworkConnection NO
CreateServer NO
CreateTCPClient NO
CreateTCPServer NO
DebugLog YES
Decode YES
Decrypt YES
DeleteEvent NO
DeleteVariable NO
DestroyServer NO
DisbableRemoteDebugging NO
EnableRemoteDebugging NO
Encode YES
Encrypt YES
ErrorLog YES
ExecuteCommand NO
FileClose YES
FileDelete YES
FileExists YES
FileFreeSpace YES
FileGetName YES
FileGetOpenedHandles YES
FileGetPos YES
FileGetSize YES
FileIsValid YES
FileList YES
FileOpen YES
FileRead Yes
FileSetPos YES
FileWrite YES
FileWriteString YES
FireEvent NO
FireEventByID NO
GetBindingAddress NO
GetBlobByName NO
GetBoundConsumerDevices NO
GetBoundProviderDevice NO
GetCapability NO
GetControllerNetworkAddress NO
GetDeviceDisplayName NO
GetDeviceID NO
GetDevicesByC4iName NO
GetDevicesByName NO
GetDeviceVariable NO
GetDeviceVariables NO
GetDriverConfigInfo NO
GetLocalAddress NO
GetLocale NO
GetMyNetworkAddress NO
GetPrivateKeyPassword YES
GetProjectItems NO
GetProxyDevices NO
GetProxyDevicesbyID NO
GetProxyDevicesByName NO
GetPushSettings NO
GetRemoteAddress NO
GetSerialSettings NO
GetSupportedCiphers YES
GetSupportedDigests YES
GetText YES
GetUniqueMAC YES
GetVariable NO
GetVersionInfo YES
GetZigbeeEUID NO
Hash YES
hexdump(strdump) YES
HMAC YES
hton_1 YES
InvalidateState NO
JSON:decode NO
JSON:encode YES
KeepReflashLock NO
KillTimer NO
Listen NO
ListEvent NO
ListGetDeviceContainer NO
ListGetDeviceName NO
ListGetItems NO
ListGetRoomID NO
ListGetSelectedDevice NO
ListGoToRoot NO
ListIsInNavigation NO
ListIsStarted NO
ListMIBReceived NO
ListNewControl NO
ListNewList NO
ListSendCommand NO
ListSetCapabilities NO
ListStart NO
ListStop NO
MediaAddAlbumInfo NO
MediaAddBroadcastAudioInfo NO
MediaAddMovieInfo NO
MediaGetAlbumInfo NO
MediaGetAlbumLocation NO
MediaGetAllAlbums NO
MediaGetAllBroadcastAudio NO
MediaGetAllMovies NO
MediaGetAllBroadcastAudioInfo NO
MediaGetDeviceContext NO
MediaGetMovieInfo NO
MediaGetMovieLocation NO
MediaGetSongInfo NO
MediaGetSongLocation NO
MediaGetSongsforAlbum NO
MediaLinkSongToAlbum NO
MediaModifyAlbumInfo NO
MediaModifyMovieInfo NO
MediaModifySongInfo NO
MediaRemoveAlbum NO
MediaRemoveAllAlbums NO
MediaRemoveAllMedia NO
MediaRemoveBroadcastAudio NO
MediaRemoveMovie NO
MediaRemoveSong NO
MediaRemoveAllMovies NO
MediaSetDeviceContent NO
NetConnect NO
NetDisconnect NO
NetPortOptions NO
Option NO
ParseIso8601DateTime YES
ParseXml YES
PBKDF2 YES
Print YES
ReadAtLeast NO
ReadUntil NO
ReadUntilOneOf NO
ReadUpTo NO
ReceivedAsync NO
ReceivedFromNetwork NO
ReceivedFromProxy NO
ReceivedFromSerial NO
RegisterVariableListewner WARNING Does not work if variable does not exist.
ReleaseReflashLock NO
RemoveDynamicBinding WARNING No Events will be sent prior to OnDriverlateInit. If an Event is required, this must be invoked in OnDriverLateInit.
RenameDevice NO
RequestReflashLock NO
RoomGetId NO
RoomSelectNav NO
ReadUntilOneNotOf NO
SendDataToUI NO
SendIR NO
SendIRStart NO
SendIRStop YES
SendToDevice NO
SendToNetwork NO
SendToProxy NO
SendToSerial NO
SendZigbeePacket NO
ServerCloseClient NO
ServerSend NO
SetBindingAddress NO
SetDeviceVariable NO
SetPropertyAttribs NO
SetTimer NO
SetVariable NO
TEADecrypt YES
TEAEncrypt YES
tohex YES
tonumber_loc YES
UnRegisterVariableListener WARNING Does not work if variable has not been registered, added or does not exist.
UpdateProperty NO
UpdatePropertyList NO
urlCancel NO
urlCancelAll NO
urlCustom NO
urlDelete NO
urlGet NO
urlGetOption NO
urlGetTickets NO
urlPost NO
urlPut NO
urlSetOption NO
urlSetProxy NO
urlSetTimeout NO
XmlEscapeString NO

OnDriver RemovedFromProject

Called whenever a driver is removed or deleted from a project. This API is useful if a driver has any cleanup requirements or needs to send any final commands to a device prior to being removed or deleted from a project. If so, those should be implemented within this function.

Available from 2.1.0

Signature

C4:OnDriverRemovedFromProject

ParseIso8601DateTime

Parses a ISO 8601 date/time stamp to UTC (Coordinated Universal Time). This API can be invoked during OnDriverInit.

Available from 2.7.0

Signature

C4:ParseIso8601DateTime(str[, strict])

Parameter Description
str The string to be parsed.
bool Optional. Strict parsing type,. Defaults to false. If enabled, leading or trailing whitespace will cause the function to fail.

Returns

Parameter Description
table similar to what a os.date("t") call would return, except that the isdst field will be missing due to it being UTC.
num The Number of the second epoch in UTC.
num The fraction of a second, expressed in microseconds.

Usage Note

If the functions fails, nothing is returned.

Example

local t, epoch, microsecs = C4:ParseIso8601DateTime("2014-01-01T12:01:00.750+01:00")
print(os.date("%x %X", os.time(t)) .. " and " .. microsecs .. " microseconds")
print("Seconds since epoch (utc) = " .. epoch)
t = C4:ParseIso8601DateTime("   2014-01-01T12:01:00.750+01:00  ", true)
print("t = " .. tostring(t))
--[[
  Example output:
   01/01/14 11:01:00 and 750000 microseconds
   Seconds since epoch (utc) = 1388574060
   t = nil
--]]

PersistDeleteAll

Deletes all values. See PersistGetValue and PersistSetValue

Available from 2.10.0

Signature

C4:PersistDeleteAll()

Parameter

None

Returns

None

Example

C4:PersistDeleteAll()

PersistGetValue

Returns the value associated with the specified name. This API can be used before OnDriverLateInit.

Available from 2.10.0

Signature

C4:PersistGetValue()

Parameter Description
str A string containing the name of the value.
bool Boolean indicating whether the value is encrypted. If true, the value is decrypted before it is returned

Returns

Parameter Description
value The value associated with the specified name, or nil if no value was found. Can be : number, string, boolean, table.

Example

local Foo = C4:PersistGetValue("Foo") 

PersistSetValue

Persists a value associated with the specified name. This API can be used before OnDriverLateInit.

Available from 2.10.0

Signature

C4:PersistSetValue(name, value, encrypted) 

Parameter Description
str A string containing the name of the value.
value The value to be persisted. The type can be any one of the following: number, string, boolean, table.

Returns

Value Description
value The value associated with the specified name, or nil if no value was found.
bool Boolean indicating whether the value is encrypted before persisting.

Usage Note

The value parameter type depends on the value that was set previously and can be one of the following: number, string, boolean, table.If the value parameter is a table, then the elements within the table must be one of the following types: number, string, boolean, table, nil. Tables can contain any combination of types, including nested tables. However, C4:PersistSetValue will fail if the table, or any nested table, contains any elements of the following types: lightuserdata, userdata, function, thread.

PersistSetValue uses its own thread for pushing values to the database. This thread doesn't start running until just before OnDriverLateInit. All values destined for the database are queued up so is lost. However, there is a window of time during which calling C4:PersistGetValue might not return values set previously with C4.PersistSetValue.

Example

C4:PersistSetValue("Foo", "Bar")
local Foo = C4:PersistGetValue("Foo")
print(Foo)

...

local Foo = {
    Biz = "Baz",
    Qux = "Norf
}

C4:PersistSetValue("Foo", Foo)

local Bar = C4:PersistGetValue("Foo")
print(Bar["Biz"])
print(Bar["Qux"])

RemoveDynamicBinding

Function called by a DriverWorks driver to remove a dynamically created binding. This API should not be invoked during OnDriverInit. No Events will be sent prior to OnDriverlateInit. If an event is required, this method must be invoked in OnDriverlateInit.

Available from 1.6.0

Signature

C4:RemoveDynamicBinding(idBinding)

Parameter Description
num ID of the dynamic binding to remove.

Returns

None

RenameDevice

The ReNameDevice API supports the ability to rename a device that is currently in a Control4 project from a driver. This API can be also called from a driver other than that of the device's. This supports that ability to rename project devices externally. This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:RenameDevice(proxyId, name) or C4:RenameDevice(deviceId, name)

Parameter Description
num The Proxy ID value of the device being renamed
num Device ID of the device being renamed.
str New device name.

Returns

None

Usage Note

Note that ComposerPro shows the Proxy Device and not the protocol drivers id.  In most cases, the Lua Driver’s deviceId is the protocol ID and is probably not the id to be changed. When this API is executed it will refresh the project. This API works if called in OnDriverLateInit. It will not work in onDriverInit.

Example

C4:RenameDevice(9, "Testing")

RoomGetId

Function to get the ID value of the room containing the driver. This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:RoomGetId()

Parameters

None

Returns

Parameter Description
int Device ID of containing room.

Example

idRoom = C4:RoomGetId()
print("Room id is " .. idRoom)

RoomSelectNav

Function to force the selection of onscreen for the selected room. This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:RoomSelectNav (int)

Parameter Description
int Device ID of the room to force onscreen selection

Returns

None

Example

C4:RoomSelectnav(C4:RoomGetId())

SendDataToUI

Function to send data to subscribed navigators. This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

This API has a dual signature. It can be used to send an XML string or a command with parameters.

C4:SendDataToUI (xml)

Parameter Description
str xml string to send

C4:SendDataToUI (strCommand, tParams)

Parameter Description
strCommand Command to be sent to subscribed navigators.
tParams Lua table of parameters for the command.

Returns

None

Usage Note

The xml must be properly formatted and escaped for the function to succeed. Only navigators that have set up subscriptions to receive data from this device will receive the sent data.

Example

Sending XML string:

C4:SendDataToUI("<myxml>xml data to be sent to navs</myxml>")

Sending command with parameters:

C4:SendDataToUI("DRIVER_COMMAND", { PARAM1 = "Data1", PARAM2 = "Data1" })

SendUIRequest

Function that sends a request to another driver. It uses the proxy or protocol ID value of the driver as a means to target the driver where the request will be sent. The driver receiving the SendUIRequest must have an a UIRequest function configured which will contain the return values requested by the SendUIRequest call.

Available from 2.9.0

Signature

C4:SendUIRequest (int,string, tParams)

Parameter Description
int Proxy or protocol ID value of the driver receiving the SendUIRequest
str Request to send in string format
table Table containing values sent with the request. If no values are needed an empty table must be sent.

Returns

Data is returned to the driver sending the SendUIRequest in XML format.

Examples

C4:SendUIRequest(231, "GET_MY_DRIVER_DATA", tParams)

The above example is used below in a driver initiating the SendUIRequest. In this example, the API contains a value of 231. This is the proxy ID value of the driver where the request is being sent. This is followed by a request called GET_MY_DRIVER_DATA. This is an expected request by the driver receiving the SendUIRequest. A table of parameters follows the command.

function TestUIRequest()
    local tParams = {}
    tParams["PARAM_X"] = 1024
    tParams["PARAM_Y"] = 768
    C4:SendUIRequest(231, "GET_MY_DRIVER_DATA", tParams)
end

To the right is an example of the required UIRequest found in the driver receiving the SendUIRequest. In this example, when the request is received it takes the values in the tParams table and, if they are not a specified value of 640 or 480, multiplies them by 10. It then formats the values into XML and returns them through retValue to the driver that initiated the SendUIRequest.

function UIRequest(sRequest, tParams)
    tParams = tParams or {}
    local param_x = tonumber(tParams["PARAM_X"]) or 640
    local param_y = tonumber(tParams["PARAM_Y"]) or 480
                   
         local value_x = param_x * 10
         local value_y = param_y * 10
                   
         local retValue = "<driver_data>"
         retValue = retValue .. "<value_x>" .. value_x .. "</value_x>"
         retValue = retValue .. "<value_y>" .. value_y .. "</value_y>"
         retValue = retValue .. "</driver_data>"
                   
    return retValue
end

The XML below the example is the returned value.

--Returned Value

<driver_data>
    <value_x>10240</value_x>
    <value_y>7680</value_y>
</driver_data>

SetPropertyAttribs

Function to modify the visibility of properties as viewed from Composer. This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:SetPropertyAttribs(string, int)

Parameter Description
str Name of property to modify
int 0 (to show) or 1 (to hide)

Returns

None

Example

The following code would hide the property named “resolution” in the Lua property page for this driver: C4:SetPropertyAttribs("Resolution", 1)

TEADecrypt

Decrypt the input string with Corrected Block TEA (XXTEA) Algorithm, using the specified key. This API can be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:TEADecrypt(strBuf, strKey)

Parameter Description
str String to be decrypted
key Key to use for decryption. Keys are 32 hex digits, encoded as a string (128-bit).

Returns

Parameter Description
str Decrypted version of input string.

Usage Note

Key must be the same for encryption / decryption to function properly. The input string (strBuf) must be padded to a 4-byte boundary. More information about the Corrected Block TEA algorithm (XXTEA) as well as a compatible C implementation of XXTEA may be found at Wikipedia: http://en.wikipedia.org/wiki/XXTEA

Example

Encrypt then Decrypt a string, then print the original string out:

local key = "1234567887654321abcdefabcabcdefa" e = C4:TEAEncrypt("Control4 Rocks! ", key) print(C4:TEADecrypt(e, key))

-- prints "Control4 Rocks!

TEAEncrypt

Encrypt the input string with Corrected Block TEA (XXTEA) Algorithm, using the specified key. This API can be invoked during OnDriverInit

Available from 1.6.0

Signature

C4:TEAEncrypt(strBuf, strKey)

Parameter Description
str String to be encrypted
key Key to use for encryption. Keys are 32 hex digits, encoded as a string (128-bit).

Returns

Parameter Description
str TEA Encrypted version of input string

Usage Note

Key must be the same for encryption / decryption to function properly. The input string (strBuf) must be padded to a 4-byte boundary. More information about the Corrected Block TEA algorithm (XXTEA) as well as a compatible C implementation of XXTEA may be found at Wikipedia: http://en.wikipedia.org/wiki/XXTEA

Example

Encrypt then Decrypt a string, then print the original string out:

local key = "1234567887654321abcdefabcabcdefa" e = C4:TEAEncrypt("Control4 Rocks! ", key) print(C4:TEADecrypt(e, key))

-- prints "Control4 Rocks!

Notification Interface

Notification Interface

Beginning with OS 3, device drivers have the ability to include .jpeg files within notifications. These images are displayed as part of the notification. The .jpeg file can be retrieved from a cloud service that supports the device, from the device itself or from a location on a Control4 Controller.

Leveraging this functionality in a driver requires the following:

  1. Configuration: New Driver XML implementation to support attachment notifications and attachment source locations
  2. Execution: API implementation for each source location needed.

Configuration

Required Driver XML: In order for a driver to support attachments within the notifications sent by the Notification Agent, the following XML element must be included and set to True:

<notification_attachment_provider>True</notification_attachment_provider>

Once set to True, the Notification Agent in ComposerPro now includes a new attachment field.

There are three types of .jpeg attachments that can be included in the Push Notification: Memory, File or Snapshot (URL). Note that any combination of the three may be implemented in the driver XML. This is largely dependent upon the device's capabilities. When the following XML is added to the driver these options are available through the Add button:

<notification_attachments>
              <attachment>
                    <id>1001</id>
                    <type>IMAGE_JPEG</type>
                    <description>Current Snapshot</description>
                    <source>MEMORY</source>
              </attachment>
              <attachment>
                    <id>1002</id>
                    <type>IMAGE_JPEG</type>
                    <description>Snapshot (FILE)</description>
                    <source>FILE</source>
              </attachment>
              <attachment>
                     <id>1003</id>
                     <type>IMAGE_JPEG</type>
                     <description>Snapshot (URL)</description>
                     <source>URL</source>
              </attachment>
 </notification_attachments>

After clicking the Add button and opening the driver, which is a security camera in this example, we can see the three image types. When the correct type for the device the driver supports is selected, the attachment field is populated.

Execution

The following APIs have been delivered in OS 3 to support the return of the .jpeg files.

GetNotificationAttachmentURL

GetNotificationAttachmentFile

GetNotificationAttachmentBytes

Each API has been engineered to deliver the file based on the location of where the file is stored. They are called when the Notification is triggered. Currently, there are three options for file storage: URL, File or Memory

Finally, the FinishedWithNotificationAttachement API has been included in the event that your driver needs to do any sort of clean-up with the stored .jpeg file.

To assist with implementation, please see the notification driver.c4z file in the Samples folder of this SDK.

GetNotificationAttachmentURL

If the .jpeg file from the device is stored on the web or in a cloud, the GetNotificationAttachmentURL API should be included in your driver to return the URL of the file.

Example

function GetNotificationAttachmentURL()
  return "http://10.12.80.4:80/snap1vga"
end

To assist with implementation, please see the notification driver.c4z file in the Samples folder of this SDK.

GetNotificationAttachmentFile

If the .jpeg file is placed on the Control4 controller by the driver, the GetNotificationAttachmentFile API should be included in your driver to return the file.

Example

function GetNotificationAttachmentFile()
    return "image.jpg"
end

To assist with implementation, please see the notification driver.c4z file in the Samples folder of this SDK.

GetNotificationAttachmentBytes

If the .jpeg file is stored in the memory of the device, the GetNotificationAttachmentBytes API should be included in your driver to return the file. Note that this API has the potential to block data if the driver takes too long to execute the function. If it takes more than one second, a log entry will be created in the director log warning that the driver took too long. This is also logged in the driver debug log file. The log entry for this is:

“The driver: \<driver name\>(\<device id\>) took more than 1 second to get the notification extractnotifcation bytes.”

Example


function GetNotificationAttachmentBytes()
  local imageData = ??? -- Get image from somewhere

    return C4:Base64Encode(imageData)
end

To assist with implementation, please see the notification driver.c4z file in the Samples folder of this SDK.

FinishedWithNotificationAttachment

This API has been included in the event that your driver needs to do any sort of clean-up with the stored .jpeg file. It also provides a notification when the original notification has been sent. This is an optional API and only recommended if cleanup is needed. For example, if it is desirable to remove a temporary image file from your system.

Example

function FinishedWithNotificationAttachment()
  -- do any cleanup required here.
end

To assist with implementation, please see the notification driver.c4z file in the Samples folder of this SDK.

Refresh Navigator

The following is an example of how to be notified when the “Refresh Navigator” call is made. When bindings, device names, or device media has changed, a “Refresh Navigator” call is made. This event is an alert for the Navigators that any cached data about the project or media may now be invalid.

Specifically the event for “Refresh Navigator” is the “OnPIP” event. To get this event, we make use of the generic event registration calls:

RegisterSystemEvent UnregisterSystemEvent UnregisterAllSystemEvents

Example

C4:RegisterSystemEvent(C4SystemEvents["OnPIP"], 0)

The C4SystemEvents variable is the array of all event name to ID’s.

Use deviceId 0 to register for device specific events for all devices. Some events are system wide and will be sent regardless of the device id that was registered, others use the device id to filter who gets what events.

Your driver will need to implement the “OnSystemEvent” method.

Example

function OnSystemEvent(data)
  print("System Event occurred - data: " .. data)
end

The “data” passed to the callback function is event specific and can be provided on an event by event basis as needed. In most cases, it can be ignored.

See Registering for System Events for additional information.

Properties Interface

Properties Table

The Lua Table ‘Properties’ contains the current value of this driver’s properties. Although you can read from this table, and change properties’ values on the devices’ Properties page, to change the value of a device property programmatically, you should use C4: UpdateProperty.

Added in 1.6.0.

Signature

Properties[strName]

Example

--Use Properties in a comparison:
if (Properties[CalculateWindShear] == true) then
        CalculateWindShear()
end

--Print out all Properties: for PropertyName, PropertyValue in pairs(Properties) do print(PropertyName, PropertyValue) end

GetProjectProperty

GetProjectProperty takes a single string parameter from a list of property names. The API returns the value of that property, if it exists.

Added in OS 3.0.0

Signature

C4:GetProjectProperty(propertyName)

Parameter Description
str Name of Property. Includes the following:

Example

Use Properties in a comparison:
if (Properties[CalculateWindShear] == true) then
        CalculateWindShear()
end

Print out all Properties:
for PropertyName, PropertyValue in pairs(Properties) do 
  print(PropertyName, PropertyValue)
end

OnPropertyChanged

Function called by Director when a property changes value.

Added in OS 1.6.0

Signature

OnPropertyChanged(strName)

Parameter Description
str Name of property that has changed.

Usage Note:

The value of the property that has changed can be found with: Properties[strName]. Note that OnPropertyChanged is not called when the Property has been changed by the driver calling the UpdateProperty command, only when the Property is changed by the user from the Properties Page.This function is called by Director when a property changes value.

Example

An example function used to process property value changes.

function OnPropertyChanged(strProperty)
  propertyValue = Properties[strProperty]
  print("strProperty = "  .. strProperty .. " changed to: " .. propertyValue)
  if (strProperty == "Security State") then
    if propertyValue == "Disarmed" then
      -- do stuff
    elseif propertyValue == "Armed Stay" then
      -- do stuff
    elseif propertyValue == "Armed Away" then
      -- do stuff
    elseif propertyValue == "Alarm Activated" then
      -- do stuff
    end
  elseif (string.find(strProperty,"Zone") ~= nil) then
    -- do stuff 
  else
    print("No action performed for " .. strProperty .. " which has been set to: " .. Properties[strProperty])
  end
end

SetPropertyAttribs

Function called from DriverWorks driver to display or hide Properties in Composer's Lua Properties page. This API should not be invoked during OnDriverInit.

Added in OS 1.6.0

Signature

C4:SetPropertyAttribs(strName, int)

Parameter Description
str Name of Property

Returns

None

Example

The example below will prevent the property named "Resolution" from being displayed in the Lua Property page for this driver.

C4:SetPropertyAttribs("Resolution", 1)

UpdateProperty

Function called from DriverWorks driver to update driver properties. This API should not be invoked during OnDriverInit.

Added in OS 1.6.0

Signature

C4:UpdateProperty(strName, strValue)

Parameter Description
str Name of Property to update.
str New value of Property.

Returns

None

Examples

Examples of how the properties are updated by the driver.

C4:UpdateProperty("Security State","Armed "..armMode)

C4:UpdateProperty("Security State","Disarmed")

UpdatePropertyList

Function called from DriverWorks driver to update driver properties. This API should not be invoked during OnDriverInit.

Added in OS 2.7.0
The strValue parameter was changed to strValueList in conjunction with OS 3.
The strValueDefault parameter was added in conjunction with OS 3.

Signature

C4:UpdatePropertyList (strName, strValueList, strValueDefault) 

Parameter Description
str Name of Property to update.
str New list for the property. This list needs to be a comma delimited list.
str Optional but Recommended New Value of the property. This value needs to be included in the list.

Returns

None

Example

C4:UpdatePropertyList("Test Dynamic List No Default", "Item 7,Item 8,Item 9", "Item 8")

Proxy Interface

GetProxyDevices

Function that returns the proxy device id(ids if device has multiple proxies) associated with the current driver. This API should not be invoked during OnDriverInit.

Added in OS 1.6.0

Signature

GetProxyDevices(strName)

Parameters

None

Returns

Value Description
num Proxy ID

Example

local proxyId = C4:GetProxyDevices()
print("proxy is: " .. proxyId)

prints: proxy is: 393

GetProxyDevicesById

Function that returns all associated proxies for a device. Return values are in ID format (numerical value). This API should not be invoked during OnDriverInit.

Added in OS 1.6.0

Signature

GetProxyDevicesById()

Parameter Description
num Device ID

Returns

Value Description
num Proxy ID

Example

C4:GetProxyDevicesById(C4:GetDeviceID())
print("dev1 is " .. dev1)
print("dev2 is " .. dev2)
print("dev3 is " .. dev3)

GetProxyDevicesByName

Function that returns the all proxy devices by proxy name. For example, if passed light.c4i it will return a list of all lights in the project. This API should not be invoked during OnDriverInit.

Added in OS 1.6.0

Signature

C4:GetProxyDevicesByName()

Parameter Description
str Driver name

Returns

Value Description
str Proxy name

Example

local proxydevs = C4:GetDevicesByC4iName("light.c4i")
if (proxydevs ~= nil) then
  print("Proxy Devices:")
  for k,v in pairs(proxydevs) do print(k,v) end
end

GetDevicesByC4iName

Function that returns specific devices by .c4i (driver) name. For example, if passed light_ip_control4_ldz-102-w-c4i it will return a list of all Control4 Wireless dimmers in the project. This API should not be invoked during OnDriverInit.

Added in OS 1.6.0

Signature

C4:GetDevicesByC4iName()

Parameter Description
str Driver name

Returns

Parameter Description
table Table of device IDs.

Example

local devs = C4:GetDevicesByC4iName("rf_internet.c4i")
    if (devs ~= nil) then
       print("Devices:")
       for k,v in pairs(devs) do print(k,v) end
    end

ReceivedFromProxy

Function called by Director when a proxy bound to the specified binding sends a BindMessage to the DriverWorks driver. This API should not be invoked during OnDriverInit.

Added in OS 1.6.0

Signature

ReceivedFromProxy(idBinding, strCommand, tParams)

Parameter Description
num Binding ID of the proxy that sent a BindMessage to the DriverWorks driver.
str Command that was sent
table Lua table of received command parameters

Returns

None

Examples

function ReceivedFromProxy(idBinding, strCommand, tParams)
 print("ReceivedFromProxy [" .. idBinding .. "]: " .. strCommand)
 if (tParams ~= nil) then
      for ParamName, ParamValue in pairs(tParams) do
           print(ParamName, ParamValue)
      end
 end
end

Map the idBinding to a variable for proxy. Evaluate the command coming in. If its a simple command, get the command equivalent out of the CMDS table, otherwise call a function to process the command.

function ReceivedFromProxy(idBinding, strCommand, tParams)
   proxy = "Undefined"
   if idBinding == 5001 then
      proxy = "Receiver"
   elseif idBinding == 5002 then
      proxy = "Tuner"
   end
   print("ReceivedFromProxy [" .. idBinding .. "]: " .. strCommand .. " for " .. proxy)
   cmd = CMDS[strCommand] 
   if (cmd ~= nill) then
     print(  "Received from Proxy: " .. strCommand .. "; Send to Device: " .. cmd)
     emit(cmd)
   else
     CommandInterpreter(strCommand, tParams)
  end
end

SendToProxy

Function called from DriverWorks driver to send a Control4 BindMessage to the proxy bound to the specified binding. This API should not be invoked during OnDriverInit.

Added in OS 1.6.0

Signature

C4:SendToProxy(idBinding, strCommand, tParams, strmessage)

or

C4:SendToProxy(idBinding, strCommand, strParam)

or

C4:SendToProxy(idBinding, strCommand, tParams, strmessage, allowEmptyValues)

Parameter Description
num Binding ID for the proxy you wish to send to
str Command to send to the proxy
table Lua table containing parameters to the command.
str COMMAND or NOTIFY – Overrides the default message for SendToProxy. See Note below.
bool Optional. When set to TRUE will allow for an empty string to be sent as a parameter value.

Usage Note

SendToProxy will send a NOTIFY if the paramater is equal to or more than a 1000 and a Command if it is less than a 1000.

Returns

None

Examples

Notify the attached contact binding that the contact has closed. Note that tParams is required, if there are no parameters, send an empty Lua table:

C4:SendToProxy(11, "CLOSED",{}, "NOTIFY")

Notify the attached thermostat binding that the temperature is now 76:

C4:SendToProxy(5001, "TEMPERATURE_CHANGED", {TEMPERATURE = 76})

Send the ‘System Armed’ text to the attached security proxy Display Text:

C4:SendToProxy(5001, "DISPLAY_TEXT", "<text>SYSTEM ARMED</text>")

Optional allowEmptyValues parameter set to True:

C4:SendToProxy(5001, "ALLOWED_FAN_MODES_CHANGED", tParams, "NOTIFY", true)

Optional allowEmptyValues parameter set to True and a table defined:

C4:SendToProxy(5001, "ALLOWED_FAN_MODES_CHANGED", {MODES = ""}, "NOTIFY", true)

Optional allowEmptyValues parameter set to True and an empty string:

C4:SendToProxy(5001, "ALLOWED_FAN_MODES_CHANGED", "", "NOTIFY", true)

Optional allowEmptyValues parameter set to True and a number:

C4:SendToProxy(5001, "ALLOWED_FAN_MODES_CHANGED", 213, "NOTIFY")

Send the ‘System Armed’ text to the attached security proxy Display Text:

C4:SendToProxy(5001, "DISPLAY_TEXT", "<text>SYSTEM ARMED</text>")

Registry Interface

Introduction

The Controller Registry APIs enables drivers to set, retrieve, and delete values that are stored in the Registry. The Registry consists of a database table stored in: /opt/control4/etc/registry.db.

The Registry associates a value with a well-known key. The registry is intended to store values that are global in nature. The Registry would be a good place for storing configuration data that pertains to all instances of a particular driver. Drivers SHOULD NOT use the registry to store state, or other data that are transient in nature.

The Registry APIs utilizes the same encoder/decoder used by the JSON APIs for Lua. Drivers using these APIs can persist numbers, strings, booleans, or tables. When retrieved, values are decoded back into the original type.

RegistryDeleteValue

Removes a key/value pair from the Registry.

Available from 2.10.4

Signature

C4:RegistryDeleteValue(key)

Parameter Description
key number: The key to be removed from the Registry

Returns

None

RegistryGetValue

Retrieves a value from the Registry.

Available from 2.10.4

Signature

C4:RegistryGetValue(key)

Parameter Description
key number: The key applicable to the value being retrieved.

Returns

Upon success, the API returns the value that was decoded from the Registry. The value can be any of the following: number, string ,boolean, table. Upon failure, the API returns nil.

RegistrySetValue

Sets the value of a Registry key/value pair. The value is updated if the specified key/value pair exists. A key/value pair is created by the API if it does not exist.

Available from 2.10.4

Signature

C4:RegistrySetValue(key, value)

Parameter Description
key number: The name of the key to which the specified value is associated.
value The name of the key to which the specified value is associated.

Returns

Upon success, the API returns the value that was decoded from the Registry. The value can be any of the following: number, string ,boolean, table. Upon failure, the API returns nil.

Scheduler Agent Interface

Overview

In conjunction with OS 3, drivers can now create, modify and delete scheduled events. These events appear in the Schedule Agent in ComposerPro. Once created, System programming can be created using the events.

Of note is the use of a unique namespace for the Scheduler APIs. Historically, API calls have been created in the same C4 namespace. For example: C4:ApiName. The Scheduler Agent APIs use their own namespace. For example: C4Scheduler:ApiName

As mentioned above, device drivers can now contain code to create, modify and delete scheduled events. A driver can only modify or delete events which were created by that driver. For example, consider that a driver has the need to create a simple, scheduled event which occurs on a single day. This event needs to occur on July 2nd, 2019. The Scheduler API AddSingleDayEntry can be used to accomplish this:

Example

function AddSingleDayEntry()
 local name = "AddSingleDayEntry Scheduled Event"
 local start_time = {
 year = 2019,
 month = 7,
 day = 2,
 hour = 21,
 minute = 30
 }

local options = { hidden = false, user_hidden = false, category = "", enabled = true, locked = false }

local eventId = C4Scheduler:AddSingleDayEntry(name, start_time, options) end AddSingleDayEntry()

This newly created Event can be used in ComposerPro programming.

Numerous date and time parameters are used by the Scheduler APIs. The acceptable ranges for those parameters are as follows:

Date Parameters:

Time Parameters

Schedule Agent - Add Event Interface

AddSingleDayEntry

This API adds an event which occurs once.

Available from 3.0.0

Signature

C4:Scheduler:AddSingleDayEntry(name, start_time, options)

Parameter Description
str String value of the name of the event being added.
table Optional table that includes: year, month, day, hour using the 24 hour clock, minute. Default time is 12:00 AM
table Table of additional, optional parameters that includes:
hidden - Boolean defaults to false. True prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean defaults to false. Setting to true prevents the Event from displaying on Navigators.
category - String value available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
value The added Event ID value.

Example

function AddSingleDayEntry()
    local name = "AddSingleDayEntry Scheduled Event"

    local start_time = {
    year = 2018,
    month = 7,
    day = 2,
    hour = 21,
    minute = 30
    }

    local options = {
    hidden = false,
    user_hidden = false,
    category = "",
    enabled = true,
    locked = false
    }

    local eventId = C4Scheduler:AddSingleDayEntry(name, start_time, options)
end
AddSingleDayEntry()

AddDailyRepeatEntry

This API adds an event which occurs repetitively.

Available from 3.0.0

Signature

C4Scheduler:AddDailyRepeatEntry(name, start_time, end_date, options)

Parameter Description
str String value of the name of the event being added.
table Optional table that includes: year, month, day, hour using the 24 hour clock. Default time is 12:00 AM
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. True prevents the Event from displaying in the Scheduler Agent in ComposerPro.
user_hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
value The added Event ID value.

Example

function AddDailyRepeatEntry()
    local name = "AddDailyRepeatEntry Scheduled Event"

    local start_time = {
    year = 2018,
    month = 6,
    day = 2,
    hour = 21,
    minute = 30
    }

    local end_date = {
    year = 2019,
    month = 7,
    day = 3
    }

    local options = {
    hidden = false,
    user_hidden = false,
    category = "",
    enabled = true,
    locked = false
    }

    local eventId = C4Scheduler:AddDailyRepeatEntry(name, start_time, end_date, options)
end
AddDailyRepeatEntry()

AddDailyRepeatRandomOffsetEntry

This API adds an event which occurs repetitively and can be offset by a range of 60 minutes.

Available from 3.0.0

Signature

C4Scheduler:AddDailyRepeatRandomOffsetEntry(name, random_range_minutes, start_time, end_date, options)

Parameter Description
str String value of the name of the event being added.
table Random range of minutes. number = number of minutes, range = (1-60)
table start time includes year, month, day, hour using 24 hour clock. minute (optional) The default time is 12:00 AM.
table end date. optional. includes: year, month, day
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Valuer Description
value The added Event ID value.

Example

function AddDailyRepeatRandomOffsetEntry()
    local name = "AddDailyRepeatRandomOffsetEntry Scheduled Event"
    local random_range_minutes = 12

    local start_time = {
    year = 2018,
    month = 6,
    day = 2,
    hour = 21,
    minute = 30
    }

    local end_date = {
    year = 2019,
    month = 7,
    day = 3
    }

    local options = {
    hidden = false,
    user_hidden = false,
    category = "",
    enabled = true,
    locked = false
    }

    local eventId = C4Scheduler:AddDailyRepeatRandomOffsetEntry(name, random_range_minutes, start_time, end_date, options)
end
AddDailyRepeatRandomOffsetEntry()

AddDailyRepeatXDaysEntry

This API adds an event which occurs repetitively, on a set number of days.

Available from 3.0.0

Signature

C4Scheduler:AddRepeatXDaysEntry(name, every_num_days, start_time, end_date, options)

Parameter Description
str String value of the name of the event being added.
table every number days includes, number, number of days, range (1-100)
table start time includes year, month, day, hour using 24 hour clock. minute is optional The default time is 12:00 AM.
table end date. optional. includes: year, month, day
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Parameter Description
value The added Event ID value.

Example

function AddDailyRepeatXDaysEntry()
    local name = "AddDailyRepeatXDaysEntry Scheduled Event"
    local every_num_days = 20

    local start_time = {
    year = 2018,
    month = 6,
    day = 2,
    hour = 21,
    minute = 30
    }

    local end_date = {
    year = 2019,
    month = 7,
    day = 3
    }

    local options = {
    hidden = false,
    user_hidden = false,
    category = "",
    enabled = true,
    locked = false
    }

    local eventId = C4Scheduler:AddDailyRepeatXDaysEntry(name, every_num_days, start_time, end_date, options)
end

AddDailyRepeatXDaysEntry()

AddDailySunriseEntry

This API adds an event which occurs daily at sunrise. Sunrise time is based data provided by Director.

Available from 3.0.0

Signature

C4Scheduler:AddDailySunriseEntry(name, start_time, end_date, options)

Parameter Description
str String value of the name of the event being added.
table start time includes year, month, day, hour using 24 hour clock. minute is optional The default time is 12:00 AM.
table end date. optional. includes: year, month, day
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Valuer Description
value The added Event ID value.

Example

function AddDailySunriseEntry()
    local name = "AddDailySunriseEntry Scheduled Event"

    local start_time = {
    year = 2018,
    month = 6,
    day = 2,
    }

    local end_date = {
    year = 2019,
    month = 7,
    day = 3
    }

    local options = {
    hidden = false,
    user_hidden = false,
    category = "",
    enabled = true,
    locked = false
    }

    local eventId = C4Scheduler:AddDailySunriseEntry(name, start_time, end_date, options)
end
AddDailySunriseEntry()

AddDailySunriseOffsetEntry

This API adds an event which occurs daily at sunset and can be offset by a range of 360 minutes. Use a negative number for pre-sunrise and a positive number for post-sunrise. Sunrise time is based data provided by Director

Available from 3.0.0

Signature

C4Scheduler:AddDailySunriseOffsetEntry(name, offset_minutes, start_time, end_date, options)

Parameter Description
str String value of the name of the event being added.
table offset minutes includes: number, number of minutes, range (-360 - 360)
table start time includes year, month, day, hour using 24 hour clock. minute is optional The default time is 12:00 AM.
table end date. optional. includes: year, month, day
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
value The added Event ID value.

Example

function AddDailySunriseOffsetEntry()
    local name = "AddDailySunriseOffsetEntry Scheduled Event"
    local offset_range_minutes = 12

    local start_time = {
    year = 2018,
    month = 6,
    day = 2,
    hour = 21,
    minute = 30
    }

    local end_date = {
    year = 2019,
    month = 7,
    day = 3
    }

    local options = {
    hidden = false,
    user_hidden = false,
    category = "",
    enabled = true,
    locked = false
    }

    local eventId = C4Scheduler:AddDailySunriseOffsetEntry(name, offset_range_minutes, start_time, end_date, options)
end
AddDailySunriseOffsetEntry()

AddDailySunriseRandomOffsetEntry

This API adds an event which occurs daily at sunrise and can be randomized by a range of 60 minutes. Sunrise time is based data provided by Director.

Available from 3.0.0

Signature

C4Scheduler:AddDailySunriseRandomOffsetEntry(name, random_range_minutes, start_time, end_date, options)

Parameter Description
str String value of the name of the event being added.
table Random range of minutes. number = number of minutes, range = (1-60)
table start time includes year, month, day, hour using 24 hour clock. minute is optional The default time is 12:00 AM.
table end date. optional. includes: year, month, day
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
value The added Event ID value.

Example

function AddDailySunriseRandomOffsetEntry()
    local name = "AddDailySunriseRandomOffsetEntry Scheduled Event"
    local random_range_minutes = 13

    local start_time = {
    year = 2018,
    month = 6,
    day = 2,
    hour = 21,
    minute = 30
    }

    local end_date = {
    year = 2019,
    month = 7,
    day = 3
    }

    local options = {
    hidden = false,
    user_hidden = false,
    category = "",
    enabled = true,
    locked = false
    }

    local eventId = C4Scheduler:AddDailySunriseRandomOffsetEntry(name, random_range_minutes, start_time, end_date, options)
end
AddDailySunriseRandomOffsetEntry()

AddDailySunsetEntry

This API adds an event which occurs daily at sunset. Sunset time is based data provided by Director.

Available from 3.0.0

Signature

C4Scheduler:AddDailySunsetEntry(name, start_time, end_date, options

Parameter Description
str String value of the name of the event being added.
table start time includes year, month, day, hour using 24 hour clock. minute is optional The default time is 12:00 AM.
table end date. optional. includes: year, month, day
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
value The added Event ID value.

Example

function AddDailySunsetEntry()
    local name = "AddDailySunsetEntry Scheduled Event"

    local start_time = {
    year = 2018,
    month = 6,
    day = 2,
    hour = 21,
    minute = 30
    }

    local end_date = {
    year = 2019,
    month = 7,
    day = 3
    }

    local options = {
    hidden = false,
    user_hidden = false,
    category = "",
    enabled = true,
    locked = false
    }

    local eventId = C4Scheduler:AddDailySunsetEntry(name, start_time, end_date, options)
end
AddDailySunsetEntry()

AddDailySunsetOffsetEntry

This API adds an event which occurs daily at sunset and can be offset by a range of 360 minutes. Use a negative number for pre-sunset and a positive number for post sunset. Sunset time is based data provided by Director.

Available from 3.0.0

Signature

C4Scheduler:AddDailySunsetOffsetEntry(name, offset_minutes, start_time, end_date, options)

Parameter Description
str String value of the name of the event being added.
table offset minutes includes: number, number of minutes, range (-360 - 360)
table start time includes year, month, day, hour using 24 hour clock. minute is optional The default time is 12:00 AM.
table end date. optional. includes: year, month, day
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Parameter Description
value The added Event ID value.

Example

function AddDailySunsetOffsetEntry()
    local name = "AddDailySunsetOffsetEntry Scheduled Event"
    local offset_minutes = 12

    local start_time = {
    year = 2018,
    month = 6,
    day = 2,
    hour = 21,
    minute = 30
    }

    local end_date = {
    year = 2019,
    month = 7,
    day = 3
    }

    local options = {
    hidden = false,
    user_hidden = false,
    category = "",
    enabled = true,
    locked = false
    }

    local eventId = C4Scheduler:AddDailySunsetOffsetEntry(name, offset_minutes, start_time, end_date, options)
end
AddDailySunsetOffsetEntry()

AddDailySunsetRandomOffsetEntry

This API adds an event which occurs daily at sunset and can be randomized by a range of 60 minutes. Sunset time is based data provided by Director.

Available from 3.0.0

Signature

C4:Scheduler:AddDailySunsetRandomOffsetEntry(name, random_range_minutes, start_time, end_date, options)

Parameter Description
str String value of the name of the event being added.
table Random range of minutes. number = number of minutes, range = (1-60)
table start time includes year, month, day, hour using 24 hour clock. minute is optional The default time is 12:00 AM.
table end date. optional. includes: year, month, day
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Parameter Description
value The added Event ID value.

Example

function AddDailySunsetRandomOffsetEntry()
    local name = "AddDailySunsetRandomOffsetEntry Scheduled Event"
    local random_range_minutes = 13

    local start_time = {
    year = 2018,
    month = 6,
    day = 2,
    hour = 21,
    minute = 30
    }

    local end_date = {
    year = 2019,
    month = 7,
    day = 3
    }

    local options = {
    hidden = false,
    user_hidden = false,
    category = "",
    enabled = true,
    locked = false
    }

    local eventId = C4Scheduler:AddDailySunsetRandomOffsetEntry(name, random_range_minutes, start_time, end_date, options)
end
AddDailySunsetRandomOffsetEntry()

AddEndOfMonthEntry

This API adds an event which occurs at the end of the month defined in the start table.

Available from 3.0.0

Signature

C4Scheduler:AddEndOfMonthEntry(name, start_time, options)

Parameter Description
str String value of the name of the event being added.
table start time includes year, month, day, hour using 24 hour clock. minute is optional The default time is 12:00 AM.
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
value The added Event ID value.

Example

function AddEndOfMonthEntry()
    local name = "AddEndOfMonthEntry Scheduled Event"

    local start_time = {
    year = 2018,
    month = 6,
    hour = 21,
    minute = 30
    }

    local options = {
    hidden = false,
    user_hidden = false,
    category = "",
    enabled = true,
    locked = false
    }

    local eventId = C4Scheduler:AddEndOfMonthEntry(name, start_time, options)
end
AddEndOfMonthEntry()

AddEndOfMonthRepeatEntry

This API adds an event which occurs at the end of every month.

Available from 3.0.0

Signature

C4Scheduler:AddEndOfMonthRepeatEntry(name, start_time, end_date, options

Parameter Description
str String value of the name of the event being added.
table start time includes year, month, day, hour using 24 hour clock. minute is optional The default time is 12:00 AM.
table end date. optional. includes: year, month, day
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
value The added Event ID value.

Example

function AddEndOfMonthRepeatEntry()
    local name = "AddEndOfMonthRepeatEntry Scheduled Event"

    local start_time = {
    year = 2018,
    month = 6,
    hour = 21,
    minute = 30
    }

    local end_date = {
    year = 2019,
    month = 7,
    day = 3
    }

    local options = {
    hidden = false,
    user_hidden = false,
    category = "",
    enabled = true,
    locked = false
    }

    local eventId = C4Scheduler:AddEndOfMonthRepeatEntry(name, start_time, end_date, options)
end
AddEndOfMonthRepeatEntry()

AddNthWeekdayOfMonthEntry

This API adds an event which occurs at the designated (Nth) day of every week in relation to that days occurrence in a month. For example, an event that occurs on the second Tuesday of the month of May.

Available from 3.0.0

Signature

C4Scheduler:AddNthWeekdayOfMonthEntry(name, period, weekday, start_time, options)

Parameter Description
str String value of the name of the event being added.
str Period values of: FIRST, SECOND, THIRD, FOURTH, LAST
str Weekday values of: SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
table start time includes year, month, day, hour using 24 hour clock. minute is optional The default time is 12:00 AM.
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
value The added Event ID value.

Examples

function AddNthWeekdayOfMonthEntry()
    local name = "AddNthWeekdayOfMonthEntry Scheduled Event"
    local period = "SECOND"
    local week_day = "MONDAY"

    local start_time = {
    year = 2018,
    month = 6,
    hour = 8,
    minute = 15
    }

    local options = {
    hidden = false,
    user_hidden = false,
    category = "",
    enabled = true,
    locked = false
    }

    local eventId = C4Scheduler:AddNthWeekdayOfMonthEntry(name, period, week_day, start_time, options)
end
AddNthWeekdayOfMonthEntry()

AddNthWeekdayOfMonthRepeatEntry

This API adds a repetitive event which occurs at the designated (Nth) day of every week in relation to that days occurrence in a month. For example, an event that occurs on the second Tuesday of every month.

Available from 3.0.0

Signature

C4Scheduler:AddNthWeekdayOfMonthRepeatEntry(name, period, weekday, start_time, end_date, options)

Parameter Description
str String value of the name of the event being added.
str Period values of: FIRST, SECOND, THIRD, FOURTH, LAST
str Weekday values of: SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
table start time includes year, month, day, hour using 24 hour clock. minute is optional The default time is 12:00 AM.
table end date. optional. includes: year, month, day
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
value The added Event ID value.

Examples

function AddNthWeekdayOfMonthRepeatEntry()
    local name = "AddNthWeekdayOfMonthRepeatEntry Scheduled Event"
    local period = "SECOND"
    local week_day = "MONDAY"

    local start_time = {
    year = 2018,
    month = 6,
    hour = 21,
    minute = 30
    }

    local end_date = {
    year = 2019,
    month = 7,
    day = 3
    }

    local options = {
    hidden = false,
    user_hidden = false,
    category = "",
    enabled = true,
    locked = false
    }

    local eventId = C4Scheduler:AddNthWeekdayOfMonthRepeatEntry(name, period, week_day, start_time, end_date, options)
end
AddNthWeekdayOfMonthRepeatEntry()

AddDaysOfTheWeekEntry

This API adds an event which occurs on defined days of the week.

Available from 3.0.0

Signature

C4:Scheduler:AddDaysOfTheWeekEntry(name, days_of_the_week, start_time, end_date, options)

Parameter Description
str String value of the name of the event being added.
str Weekday values of: SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
table start time includes year, month, day, hour using 24 hour clock. minute is optional The default time is 12:00 AM.
table end date. optional. includes: year, month, day
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Valuer Description
value The added Event ID value.

Examples

function AddDaysOfTheWeekEntry()
    local name = "AddDaysOfTheWeekEntry Scheduled Event"
    local days_of_the_week = {"MONDAY", "WEDNESDAY", "FRIDAY"}

    local start_time = {
    year = 2018,
    month = 6,
    day = 12,
    hour = 8,
    minute = 15
    }

    local options = {
    hidden = false,
    user_hidden = false,
    category = "",
    enabled = true,
    locked = false
    }

    local eventId = C4Scheduler:AddDaysOfTheWeekEntry(name, days_of_the_week, start_time, options)
end
AddDaysOfTheWeekEntry()

AddEveryXMonthsEntry

This API adds an event which occurs set number of months. For example, an event that occurs every 4 months.

Available from 3.0.0

Signature

C4:Scheduler:AddEveryXMonthsEntry(name, num_months, start_time, end_date, options

Parameter Description
str String value of the name of the event being added.
table number of months. range (1-100)
table start time includes year, month, day, hour using 24 hour clock. Minute is optional The default time is 12:00 AM.
table end date. optional. includes: year, month, day
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
value The added Event ID value.

Examples

function AddEveryXMonthsEntry()
    local name = "AddEveryXMonthsEntry Scheduled Event"
    local num_months = 3

    local start_time = {
    year = 2018,
    month = 6,
    day = 12,
    hour = 8,
    minute = 15
    }

    local options = {
    hidden = false,
    user_hidden = false,
    category = "",
    enabled = true,
    locked = false
    }

    local eventId = C4Scheduler:AddEveryXMonthsEntry(name, num_months, start_time, options)
end
AddEveryXMonthsEntry()

AddSetDaysEveryXWeeksEntry

This API adds an event which occurs on the same day(s) of the week over a defined period of weeks. For example, an event that occurs every Tuesday and Wednesday - every three weeks

Available from 3.0.0

Signature

C4:Scheduler:AddSetDaysEveryXWeeksEntry(name, days_of_the_week, num_weeks, start_time, end_date, options)

Parameter Description
str String value of the name of the event being added.
str Weekday values of: SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
num Value between 1 and 100. Number of week between the event occurring
table start time includes year, month, day, hour using 24 hour clock. Minute is optional The default time is 12:00 AM.
table end date. optional. includes: year, month, day
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
value The added Event ID value.

Examples

function AddSetDaysEveryXWeeksEntry()
    local name = "AddSetDaysEveryXWeeksEntry Scheduled Event"
    local days_of_week = {"MONDAY", "WEDNESDAY", "FRIDAY"}
    local num_weeks = 3

    local start_time = {
    year = 2018,
    month = 6,
    day = 12,
    hour = 8,
    minute = 15
}

    local options = {
    hidden = false,
    user_hidden = false,
    category = "",
    enabled = true,
    locked = false
    }

    local eventId = C4Scheduler:AddSetDaysEveryXWeeksEntry(name, days_of_week, num_weeks, start_time)
end
AddSetDaysEveryXWeeksEntry()

AddSetDaysEveryXYearsEntry

This API adds an event which occurs set number of years. For example, an event that occurs every 4 years.

Available from 3.0.0

Signature

C4:Scheduler:AddEveryXYearsEntry(name, num_years, start_time, end_date, options)

Parameter Description
str String value of the name of the event being added.
table number of years. range: (1-100)
table start time includes year, month, day, hour using 24 hour clock. Minute is optional The default time is 12:00 AM.
table end date. optional. includes: year, month, day
table Table of additional, optional parameters that includes:
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
value The added Event ID value.

Examples

function AddEveryXYearsEntry()
    local name = "AddEveryXYearsEntry Scheduled Event"
    local num_years = 3

local start_time = { year = 2018, month = 6, day = 5, hour = 21, minute = 30 }

local options = { hidden = false, user_hidden = false, category = "", enabled = true, locked = false }

local eventId = C4Scheduler:AddEveryXYearsEntry(name, num_years, start_time) end AddEveryXYearsEntry()

Schedule Agent - Delete Event Interface

DeleteEntryByID

Deletes and Event based on the Event ID value passed. A driver can only delete events which were created by that driver.

Available from 3.0.0

Signature

C4:Scheduler:DeleteEntryByID (event_id)

Parameter Description
num ID value of the name of the event being deleted.

DeleteEntryByName

Deletes and Event based on the Event Name value passed. A driver can only delete events which were created by that driver.

Available from 3.0.0

Signature

C4Scheduler:DeleteEntryByName(name)

Parameter Description
str Value of the name of the event being deleted.

Schedule Agent - Get Event Interface

GetEntries

Deletes an Event based on the Event ID value passed. A driver can only delete events which were created by that driver.

Available from 3.0.0

Signature

C4Scheduler:GetEntries()

Parameter Description
Value Description
table ID/Name key value pairs. The entries returned are only entries created by the driver. For example:
{
 1  entry1name
 2  entry2name
 3  entry3name
 4  entry4name
}   

GetEntry

The entry returned can only be an entry created by the driver.

Available from 3.0.0

Signature

C4Scheduler:GetEntry(event_id) 

Parameter Description
num ID number of the event.

Returns

Value Description
table Enabled - true/false
Description <string>
Eventid <event id>
creator_state <string>
hidden true/false
creatorid <creator id>
category <string>
locked true/false
xml <xml string> (see example below)
user_hidden true/false

 

Example

Sample XML – Varies depending on the settings of the event
<entry>
    <eventid>10</eventid>
    <description>AddDailyRepeatRandomOffsetEntry Scheduled Event</description>
    <category>daily_repeat</category>
    <enabled>False</enabled>
    <locked>True</locked>
    <creatorid>6</creatorid>
    <creatorstate></creatorstate>
    <hidden>False</hidden>
    <user_hidden>True</user_hidden>
    <start>
        <offset>0</offset>
        <offset_minutes>1293</offset_minutes>
        <start_date>
            <start_day>2</start_day>
            <start_month>7</start_month>
            <start_year>2018</start_year>
            <start_period>0</start_period>
            <start_weekday>0</start_weekday>
        </start_date>
        <randomize>12</randomize>
    </start>
    <repeat>
        <frequency>1</frequency>
        <rate>1</rate>
        <daymask>0</daymask>
        <end_date>
            <end_month>9</end_month>
            <end_day>23</end_day>
            <end_year>2019</end_year>
        </end_date>
    </repeat>
</entry>

Schedule Agent - Modify Event Interface

ModifySingleDayEntry

Modifies the Event based on the Event ID passed. This API uses the parameters found in the Single Day Entry API for convenience. A driver can only modify events which were created by that driver.

Available from 3.0.0

Signature

C4Scheduler:ModifySingleDayEntry(name, start_time, options)

Parameter Description
str String value of the name of the event being modified.
table Includes year, month, day, hour using 24 hour clock. Minute is optional The default time is 12:00 AM.
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
True Successful
False Modification failed

ModifyDailyRepeatEntry

Modifies the Event based on the Event ID passed. This API uses the parameters found in the Daily Repeat Entry API for convenience. A driver can only modify events which were created by that driver.

Available from 3.0.0

Signature

C4Scheduler:ModifyDailyRepeatEntry(event_id, name, start_time, end_date, options)

Parameter Description
str String value of the name of the event being modified.
table Includes year, month, day, hour using 24 hour clock. Minute is optional. The default time is 12:00 AM.
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
True Successful
False Modification failed

ModifyDailyRepeatRandomOffsetEntry

Modifies the Event based on the Event ID passed. This API uses the parameters found in the Daily Repeat Random Offset Entry API for convenience. A driver can only modify events which were created by that driver.

Available from 3.0.0

Signature

C4Scheduler:ModifyDailyRepeatRandomOffsetEntry(name, random_range_minutes, start_time, end_date, options)

Parameter Description
str String value of the name of the event being modified.
table Random range of minutes. number = number of minutes, range = (1-60)
table start time includes year, month, day, hour using 24 hour clock. Minute is optional. The default time is 12:00 AM.
table end date. optional. includes: year, month, day
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
True Successful
False Modification failed

ModifyDailyRepeatXDaysEntry

Modifies the Event based on the Event ID passed. This API uses the parameters found in the Daily Repeat X Days Entry API for convenience. A driver can only modify events which were created by that driver.

Available from 3.0.0

Signature

C4Scheduler:ModifyDailyRepeatXDaysEntry(name, every_num_days, start_time, end_date, options)

Parameter Description
str String value of the name of the event being modified.
table every number days includes, number, number of days, range (1-100)
table start time includes year, month, day, hour using 24 hour clock. Minute is optional. The default time is 12:00 AM.
table end date. optional. includes: year, month, day
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
True Successful
False Modification failed

ModifyDailySunriseEntry

Modifies the Event based on the Event ID passed. This API uses the parameters found in the Daily Sunrise Entry API for convenience. A driver can only modify events which were created by that driver.

Available from 3.0.0

Signature

C4Scheduler:ModifyDailySunriseEntry(name, start_time, end_date, options

Parameter Description
str String value of the name of the event being modified.
table start time includes year, month, day, hour using 24 hour clock. Minute is optional. The default time is 12:00 AM.
table end date. optional. includes: year, month, day
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
True Successful
False Modification failed

ModifyDailySunriseOffsetEntry

Modifies the Event based on the Event ID passed. This API uses the parameters found in the Daily Sunrise Offset Entry API for convenience. A driver can only modify events which were created by that driver

Available from 3.0.0

Signature

C4Scheduler:ModifyDailySunriseOffsetEntry(name, offset_minutes, start_time, end_date, options)

Parameter Description
str String value of the name of the event being modified.
table offset minutes includes: number, number of minutes, range (-360 - 360)
table start time includes year, month, day, hour using 24 hour clock. Minute is optional. The default time is 12:00 AM.
table end date. optional. includes: year, month, day
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
True Successful
False Modification failed

ModifyDailySunriseRandomOffsetEntry

Modifies the Event based on the Event ID passed. This API uses the parameters found in the Daily Sunrise Random Offset Entry API for convenience. A driver can only modify events which were created by that driver.

Available from 3.0.0

Signature

C4Scheduler:ModifyDailySunriseRandomOffsetEntry(name, random_range_minutes, start_time, end_date, options)

Parameter Description
str String value of the name of the event being modified.
table Random range of minutes. number = number of minutes, range = (1-60)
table start time includes year, month, day, hour using 24 hour clock. Minute is optional. The default time is 12:00 AM.
table end date. optional. includes: year, month, day
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
True Successful
False Modification failed

ModifyDailySunsetEntry

Modifies the Event based on the Event ID passed. This API uses the parameters found in theDaily Sunset Entry API for convenience. A driver can only modify events which were created by that driver.

Available from 3.0.0

Signature

C4Scheduler:ModifyDailySunsetEntry(name, start_time, end_date, options

Parameter Description
str String value of the name of the event being modified.
table start time includes year, month, day, hour using 24 hour clock. Minute is optional. The default time is 12:00 AM.
table end date. optional. includes: year, month, day
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
True Successful
False Modification failed

ModifyDailySunsetOffsetEntry

This API allows you to modify the Daily Sunset Offset Entry event. Use a negative number for before sunset and a positive number for number of minutes after sunset. Modifies the Event based on the Event ID passed. This API uses the parameters found in the Daily Sunset Offset Entry API for convenience. A driver can only modify events which were created by that driver.

Available from 3.0.0

Signature

C4Scheduler:ModifyDailySunsetOffsetEntry(name, offset_minutes, start_time, end_date, options)

Parameter Description
str String value of the name of the event being modified.
table offset minutes includes: number, number of minutes, range (-360 - 360)
table start time includes year, month, day, hour using 24 hour clock. Minute is optional. The default time is 12:00 AM.
table end date. optional. includes: year, month, day
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
True Successful
False Modification failed

ModifyDailySunsetRandomOffsetEntry

Modifies the Event based on the Event ID passed. This API uses the parameters found in the Daily Sunset Random Offset Entry API for convenience. A driver can only modify events which were created by that driver.

Available from 3.0.0

Signature

C4Scheduler:ModifyDailySunsetRandomOffsetEntry(name, random_range_minutes, start_time, end_date, options)

Parameter Description
str String value of the name of the event being modified.
table Random range of minutes. number = number of minutes, range = (1-60)
table start time includes year, month, day, hour using 24 hour clock. Minute is optional. The default time is 12:00 AM.
table end date. optional. includes: year, month, day
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
True Successful
False Modification failed

ModifyEndOfMonthEntry

Modifies the Event based on the Event ID passed. This API uses the parameters found in the End of Month API for convenience. A driver can only modify events which were created by that driver.

Available from 3.0.0

Signature

C4Scheduler:ModifyEndOfMonthEntry(name, start_time, options)

Parameter Description
str String value of the name of the event being modified.
table start time includes year, month, day, hour using 24 hour clock. Minute is optional. The default time is 12:00 AM.
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
True Successful
False Modification failed

ModifyEndOfMonthRepeatEntry

Modifies the Event based on the Event ID passed. This API uses the parameters found in the End of Month Repeat Entry API for convenience. A driver can only modify events which were created by that driver

Available from 3.0.0

Signature

C4Scheduler:ModifyEndOfMonthRepeatEntry(name, start_time, end_date, options)

Parameter Description
str String value of the name of the event being modified.
table start time includes year, month, day, hour using 24 hour clock. Minute is optional. The default time is 12:00 AM.
table end date. optional. includes: year, month, day
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
True Successful
False Modification failed

ModifyNthWeekdayOfMonthEntry

Modifies the Event based on the Event ID passed. This API uses the parameters found in the Nth Weekday of Month Entry API for convenience. A driver can only modify events which were created by that driver

Available from 3.0.0

Signature

C4Scheduler:ModifyNthWeekdayOfMonthEntry(name, period, weekday, start_time, options)

Parameter Description
str String value of the name of the event being modified.
str Period values of: FIRST, SECOND, THIRD, FOURTH, LAST
str Weekday values of: SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
table start time includes year, month, day, hour using 24 hour clock. Minute is optional. The default time is 12:00 AM.
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
True Successful
False Modification failed

ModifyNthWeekdayOfMonthRepeatEntry

Modifies the Event based on the Event ID passed. This API uses the parameters found in the Nth Weekday of Month Entry Repeat API for convenience. A driver can only modify events which were created by that driver.

Available from 3.0.0

Signature

C4Scheduler:ModifyNthWeekdayOfMonthRepeatEntry(name, period, weekday, start_time, end_date, options)

Parameter Description
str String value of the name of the event being modified.
str Period values of: FIRST, SECOND, THIRD, FOURTH, LAST
str Weekday values of: SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
table start time includes year, month, day, hour using 24 hour clock. Minute is optional. The default time is 12:00 AM.
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
True Successful
False Modification failed

ModifyDaysOfTheWeekEntry

Modifies the Event based on the Event ID passed. This API uses the parameters found in the Days of the Week Entry API for convenience. A driver can only modify events which were created by that driver.

Available from 3.0.0

Signature

C4Scheduler:ModifyDaysOfTheWeekEntry(name, days_of_the_week, start_time, end_date, options)

Parameter Description
str String value of the name of the event being modified.
str Weekday values of: SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
table start time includes year, month, day, hour using 24 hour clock. Minute is optional. The default time is 12:00 AM.
table end date. optional. includes: year, month, day
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
True Successful
False Modification failed

ModifyEveryXMonthsEntry

Modifies the Event based on the Event ID passed. This API uses the parameters found in the Every X Months Entry API for convenience. A driver can only modify events which were created by that driver.

Available from 3.0.0

Signature

C4Scheduler:ModifyEveryXMonthsEntry(name, num_months, start_time, end_date, options)

Parameter Description
str String value of the name of the event being modified.
table number of months. range (1-100)
table start time includes year, month, day, hour using 24 hour clock. Minute is optional. The default time is 12:00 AM.
table end date. optional. includes: year, month, day
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
True Successful
False Modification failed

ModifyEveryXYearsEntry

Modifies the Event based on the Event ID passed. This API uses the parameters found in the Every X Years Entry API for convenience. A driver can only modify events which were created by that driver.

Available from 3.0.0

Signature

C4Scheduler:ModifyEveryXYearsEntry(name, num_years, start_time, end_date, options

Parameter Description
str String value of the name of the event being modified.
table number of years. range (1-100)
table start time includes year, month, day, hour using 24 hour clock. Minute is optional. The default time is 12:00 AM.
table end date. optional. includes: year, month, day
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
True Successful
False Modification failed

ModifySetDaysEveryXWeeksEntry

Modifies the Event based on the Event ID passed. This API uses the parameters found in the Set Days Every X Weeks Entry API for convenience. A driver can only modify events which were created by that driver

Available from 3.0.0

Signature

C4Scheduler:ModifySetDaysEveryXWeeksEntry(name, days_of_the_week, num_weeks, start_time, end_date, options)

Parameter Description
str String value of the name of the event being modified.
str Weekday values of: SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
num Value between 1 and 100. Number of week between the event occurring
table start time includes year, month, day, hour using 24 hour clock. Minute is optional. The default time is 12:00 AM.
table end date. optional. includes: year, month, day
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
user_hidden - Boolean. Defaults to false. Setting user hidden to true prevents the Event from displaying on Navigators.
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
enabled - Boolean which defaults to true. Setting enabled to false will disable the Event.
locked - Boolean which defaults to false. Setting enabled to true will place the Event in a read only state.

Returns

Value Description
True Successful
False Modification failed

ModifyName

Modifies the name of an Event. A driver can only modify events which were created by that driver.

Available from 3.0.0

Signature

C4Scheduler:ModifyName(event_id, name)

Parameter Description
num Number value of the Event.
str String of Event name.

ModifyOptions

Modifies the options of an Event. A driver can only modify events which were created by that driver.

Available from 3.0.0

Signature

C4Scheduler:ModifyStartDate(event_id, options)

Parameter Description
num Number value of the Event.
table Table of additional, optional parameters that includes:
hidden - Boolean. Defaults to false. Setting to true prevents the Event from displaying in the Scheduler Agent in ComposerPro
category - String value that is available to the driver writer to use however they see fit. Can be used to categorize events.
bool - Defaults to true. Setting enabled to false will disable the Event.
bool - Defaults to false. Setting enabled to true will place the Event in a read only state.

ModifyStartDate

Modifies the Start Date of an Event. A driver can only modify events which were created by that driver.

Available from 3.0.0

Signature

C4Scheduler:ModifyStartDate(event_id, year, month, day)

Parameter Description
num Number value of the Event.
num Number value of the year.
num Number value of the month.
num Number value of the day.

ModifyStartTime

Modifies the Start Time of an Event. A driver can only modify events which were created by that driver.

Available from 3.0.0

Signature

C4Scheduler:ModifyStartDate(event_id, hour, minute)

Parameter Description
num Number value of the Event.
num Number value of the hour.
num Number value of the minute.

Serial and Network Interface

CreateNetworkConnection

Function that defines a dynamic Network Connection so no Connection XML is required. Further (port-specific configuration) can be accomplished through the use of the NetPortOptions API. Connections are actually made using the NetConnect API. This API should not be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:CreateNetworkConnection (idBinding, strAddress, strConnectionType)

Parameter Description
num id of the Network Binding to create.
str Network address or hostname that this network connection will use.
str Optional string designating connection type

Returns

None

Usage Notes

This is an alternative to having the connection section in the XML that creates the network connection

This binding parameter is used for other network calls: OnNetworkStatusChanged, C4:NetConnect & C4:NetDisconnect. Note that all Binding ID values must be unique. Duplication of Binding IDs is not permitted within the same system. Binding Ranges include:

Example

C4:CreateNetworkConnection (6000, "196.120.10.10", "SSL")

GetBindingAddress

Returns a physical (IP) address of a network binding. This API should not be invoked during OnDriverInit

Available from 1.6.0.

Signature

C4: GetBindingAddress (idBinding)

Parameter Description
num Binding value.

Returns

Value Description
str Network address or hostname that this network connection will use.
int IP address of a network binding

GetBoundConsumerDevices

Call to retrieve the devices bound to (the consumers of) a binding provided (an output binding) by this device. This API should not be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:GetBoundConsumerDevices ()

Parameter Description
num The id of the device to check the bindings on.
num Binding ID.

Usage Note

Note that for devices with a protocol and one or more proxy devices, the device id should be that of the proxy (not the lua protocol device id). A device id of 0 will use the current device id.

Returns

null if no bindings or a table of device id/device name pairs of bound devices.

Examples

First get the proxy device id to check on. In this case, the 0 means this device, and the 5001 is the proxy id for the receiver.

C4:GetBoundConsumerDevices(0, 5001)

if (devs ~= nil) then
 for id,name in pairs(devs) do
   --should be only one
   g_recProxyId = id
 end
end

Now that we have the device id of the receiver proxy device, check to see what is bound to binding id 2000:

C4:GetBoundConsumerDevices(g_recProxyId, 2000)

if (devs ~= nil) then
 for id,name in pairs(devs) do
   print ("id " .. id .. " name " .. name)
 end
end

Output:
id 19 name Television
id 67 name Television2

GetBoundProviderDevice

Call to retrieve what device is attached to an input binding of the specified device. This API should not be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:GetBoundProviderDevices()

Parameter Description
num The id of the device to check the bindings on.
num Binding ID.

Usage Note

Note that for devices with a protocol and one or more proxy devices, the device id should be that of the proxy (not the lua protocol device id). A device id of 0 will use the current device id.

Returns

null if no bindings or a table of device id/device name pairs of bound devices.

Example

First get the proxy device id to check on. In this case, the 0 means this device and the 5001 is the proxy ID for the receiver.

C4:GetBoundConsumerDevices(0,5001)

if (devs ~= nil) then
for id,name in pairs(devs) do
--should be only on g_recProxyId = id
end
end
-- the id 1011 is the video 2 input for this device
id = C4:GetBoundProviderDevice(g_recProxyId, 1011)
print("Id is " .. id)
Output:
Id is 44

GetControllerNetworkAddress

Function that returns the address of the master controller in a project. This API should not be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:GetBoundConsumerDevices()

Parameters

None

Returns

Value Description
str Network address of the master controller in IP format

GetDeviceDisplayName

Returns the name of the device as shown in Composer. This API should not be invoked during OnDriverInit

Available from 1.6.0.

Signature

C4:GetDeviceDisplayName ()

Parameter Description
num ID Value of a device. Optional

Returns

Value Description
str Name of device.

GetDeviceMAC

Returns the MAC Address associated with a device that has already been identified in the Control4 Project. The API uses address resolution protocol (ARP) queries to lookup MAC hardware addresses. It will return a value of nil if the MAC address is not found in the controller's ARP tables. Considerations when using GetDeviceMAC include:

  1. If a device responds to a search protocol (SSDP/SDDP/DDDP), a high probability exists that there will be an entry for the device in the ARP tables.
  2. If a device doesn't respond to a search protocol, establishing a connection to the device is usually sufficient to ensure that there's an entry in the ARP tables.
  3. If a device goes to sleep or is otherwise offline for any reason, then there is a low probability that there will be an entry in the ARP tables.

Available from 2.10.0

Signature

C4:GetDeviceMAC ()

Parameter Description
num Network Binding ID value for the identified device

Returns

Single MAC address.

Example

local mac = C4:GetDeviceMAC(6001)
print(mac)
 The output would appear as:

 28:39:5E:45:1F:F7

GetDiscoveryInfo

Returns a table that contains the device's discovery information.

Available from 2.10.0

Signature

C4:GetDiscoveryInfo(idBinding)

Parameter Description
num Network Binding ID value for the identified device

Returns

Table that contains the discovery information.

Example

info = C4:GetDiscoveryInfo(6001)

print(info["uuid"])

Usage Note: Return table values are based on the discovery mechanism of the device. Values included in the return table can include:

Note that C4:GetDiscoveryInfo() is not available at the time that OnDriverLateInit() is executed when Director is starting. Director doesn't startup it's discovery mechanism until well after late initialize, so providing discovery info at that point is not possible. It is recommended recommendation here is to listen for the OnSDDPDeviceStatus (#78) system event. This event includes the UUID by which the device was identified, and a boolean indicating whether the device is online. It's either that or set a timer and poll until GetDiscoveryInfo returns what you're looking for.

SDDP is a royalty-free technology that enables your device to be automatically detected by and added into customers’ Control4 systems. SDDP greatly reduces the potential for mistakes and time required for installations. Our 3,500+ dealers much prefer (and seek out) products with SDDP. SDDP is very simple to implement and we can assist you as needed.

GetMyNetworkAddress

API that returns the bound address of the "device." For example, in the case of a single network binding, GetMyNetworkAddress returns the address of the device that's connected to the driver. This API should not be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:GetMyNetworkAddress

GetNetworkBindingsByDevice

Function that returns network binding information for a device.

Available from 3.0.0

Signature

C4:GetNetworkBindingsByDevice()

Parameter Description
num The id of the device returning network binding information.

Usage Note

Note that for devices with a protocol and one or more proxy devices, the device id should be that of the proxy (not the .lua protocol device id). A device id of 0 will use the current device id.

Returns

Network Binding information for the device.

Example

C4:GetNetworkBindingsByDevice(20)

Returns:

deviceid: 20
type: 1
autobind: false
class: RS_232
1: Serial3X
rank: 0
bindingid: 15
binding_info: 
flags: 0
isbound: false
name: SERIAL 3
provider: true

deviceid: 20
type: 1
autobind: false
class: IR_OUT
1: Serial4X
rank: 0
bindingid: 401
binding_info: 
flags: 0
isbound: false
name: IR OUT 2
provider: true

GetNetworkConnections

Function that returns a table containing all of the device connections as well as data for each individual connection.

Available from 3.0.0

Signature

C4:GetNetworkBindingsByDevice()

Parameter Description
table Table containing connection information for the device and Information for each connection.

Usage Note

Note that table data will vary based on device. Below are examples of each of the connection types supported by the function. Note the type table element. This is a numeric value between 0 and 8. The values are:

Returns

Network Binding information for the device.

Examples

The examples shown to the right return tables for each connection type:

Home Controller using a UUID connection. Note the state of 1 which indicates an active connection:

UUID
firmware:  
address:  127.0.0.1
type:  1
bindingid:  6001
deviceid:  63
state:  1
gateway:  
name:  Home Controller EA5
port:  5116

Control4 8-Channel Relay using an IP connection. Note the state of 0 which indicates as inactive connection:

IP
address:  
type:  2
state:  0
deviceid:  43
firmware:  
gateway:  
name:  8-Channel Relay P1S3
bindingid:  6001

Control4 Configurable Keypad using a Zigbee connection:

Zigbee
firmware:  4.1.22
address:  000fff000077f532
type:  3
bindingid:  6001
deviceid:  75
state:  1
gateway:  
name:  Configurable Keypad
port:  7900

HOSTNAME - A HOSTNAME connection type returns a valid URL such as:

http://control4.com

A driver that uses an SSL connection:

SSL
address:  192.168.1.123
type:  5
state:  1
deviceid:  216
firmware:  
gateway:  
name:  Driver Properties
bindingid:  6001

SSL HOSTNAME - An SSL HOSTNAME connection type returns a valid, secure URL such as:

https://control4.com

UNIX DOMAIN SOCKET - A Unix Domain Socket connection type returns connection information between processes executing on the same Host, such as Director.

Z-Wave Dimmer:

Z-Wave
device_lights:  green
network_status:  online
state:  1
firmware:  
type:  8
uuid:  zwave:cd94eba9:11
security_status:  notSupported
address:  cd94eba9:11
driver_enabled:  1
deviceid:  25
wake_status:  awake
device_status:  ready
gateway:  
name:  Leviton Z-Wave DZPD3 Lamp Dimmer Module
port:  0

GetProxyDevicesbyID

Returns the Proxy ID value when passed a Device ID value. This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:GetProxyDevicesbyID (idDevice)

Parameter Description
num ID value of a device. Optional

Returns

Value Description
num Proxy ID value

Usage Note

Usage Note: If parameter passed is zero (0), this function will return the current Proxy ID for the driver selected in the Composer Project. If multiple proxies are associated with a device, the first Proxy ID displayed will be the first proxy as displayed in the Composer device tree.

GetSerialSettings

Returns the <serialsettings> string from the driver that is connected to the provided control binding. The control binding should be an RS232 provider binding. This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:GetSerialSettings (idBinding)

Parameter Description
num Control Binding Value

Returns

Value Description
str Serial Settings Data in string format.

ReceivedFromSerial

Function which dumps the data received from serial (hex format) for inspection via print. It then evaluates the response for specific delimiters and extracts the necessary components which are then used to do something. This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:ReceivedFromSerial(idBinding, strData)

Parameter Description
num ID of the serial interface the data was received on
str Data received from the serial interface

Returns

None

Usage Note

Serial data received may contain NULL characters. NULL (‘\0’) is a valid character and Lua strings handle embedded NULL characters. Serial data received may only include part of a protocol command from the connected device. It is the driver’s responsibility to re-constitute and parse the commands received from the device.

Example

function ReceivedFromSerial(idBinding, strData)
   print("Received something from serial on binding " .. idBinding)
   hexdump(strData)
   responseCount=0
   l_string = strData
   for w in string.gmatch(strData, "!1(...)") do
      retType = w
      responseCount=responseCount +1
      delimPos = string.find(l_string,tohex("1A"))
      retValue = string.sub(l_string,6, tonumber(delimPos)-1)
      l_string = string.sub(l_string,delimPos+1)
      sendNotify()
   end
end

ReceivedFromNetwork

Function which combines the data received from the network into a variable for processing when the connection status changes. This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:ReceivedFromNetwork(idBinding, nPort, strData) 

Parameter Description
num Binding ID of the interface the data was received from
num Network Port the data was received on
str Network data from the specified binding and port

Returns

None

Usage Note

Network data received may contain NULL characters. NULL (‘\0’) is a valid character and Lua strings handle embedded NULL characters.Network data received may only include part of a protocol command from the connected device. It is the driver’s responsibility to re-constitute and parse the commands received from the device.

Example

function ReceivedFromNetwork(idBinding, nPort, strData)
  -- Save up things coming back on HTTP port, process when done     
    sending to us...
  g_Receivebuffer = g_Receivebuffer .. strData
end

SetBindingAddress

Function that allows a TCP/IP device, with an existing connection, to use a different IP Address for connection purposes. This API can be used with both statically created connections (XML) as well as dynamically created ones. It is recommended that the NetConnect API is called after SetBindingAddress. This API should not be invoked during OnDriverInit.

Available from 2.8.0

Signature

C4:SetBindingAddress(idBinding, strIPaddress) 

Parameter Description
num Binding ID of the existing network binding
str New IP address for the connection

Returns

None

Example

C4:SetBindingAddress(6002, '192.168.1.225')

SetBindingStatus

Function that enables a Lua driver to explicitly set the "connected" state for a connection binding. This can particularly useful for connection bindings that aren't persistent (i.e., always connected), such as HTTP. Such non-persistent connections are marked as Offline (yellow) in the Network Tools windows in Composer. The C4:SetBindingStatus function enables a driver to manage the "connected" state of a connection binding, effectively overriding the default behavior provided by Director

Available from 2.10.0

Signature

C4:SetBindingStatus(idBinding, strStatus)

Parameter Description
num Binding ID of the existing network binding
str String that specifies the status to set.

Usage Note

The string parameter can be one of the following values: unknown: This is the default if there have been no prior calls to C4:SetBindingStatus or if the value of the status parameter is anything other than "online" or "offline".

Returns

None

Example

C4:SetBindingStatus(6001, "online") 

SendBroadcast

Function that enables a Lua driver to send network broadcast messages. The function opens a UDP connection, sets the SO_BROADCAST socket option and then sends a specified payload to the directed broadcast address. For example, 192.168.1.255. If the directed broadcast address is unavailable for any reason then the limited broadcast address is used instead, for example: 255.255.255.255.

This function must be used judiciously as there are network performance implications associated with its use. Network broadcasting requires that the router send the message to every device connected to the network. Overuse of this function can cause significant performance problems that affect the entire network.

Available from 2.10.0

Signature

C4:SendBroadcast(payload, port))

Parameter Description
str Payload of the message to be broadcast
num Port identifying the port to which the payload is broadcast.

Returns

None

Usage Note:

There are some limitations associated with network broadcasting. These include the inability for it to work beyond the local network. Messages are not broadcast to the Internet, for example. Also, there is no confirmation that the message was received.

Example

C4:SendBroadcast("This is a message, 42) 

SendToDevice

Function called from DriverWorks driver to send a Control4 CommandMessage to the specified Control4 device driver. This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:SendToDevice(idDevice, strCommand, tParams, AllowEmptyValues logCommand))

Parameter Description
num Device ID of the driver you wish to send the command to.
str Command to be sent
table Lua table of parameters for the command.
bool allowEmptyValues (T/F) Optional. Defaults to False. TRUE will allow for an empty string to be sent as a parameter value.
bool logCommand Defaults to True. False prevents this API’s content from being logged.

Usage Note

The logCommand parameter may be useful if sensitive data is being passed through the API and it is desirable for that data to not appear in logs.

Returns

None

Usage Note:

There are some limitations associated with network broadcasting. These include the inability for it to work beyond the local network. Messages are not broadcast to the Internet, for example. Also, there is no confirmation that the message was received.

Example

Toggles the Light registered with the system as device 41:

C4:SendToDevice(41,"TOGGLE",{})
-- Ramps the Light registered with the system as device 41 to 60% over 3 seconds:
C4:SendToDevice(41,"RAMP_TO_LEVEL", {LEVEL = 60, TIME = 3000})

SendToNetwork

Function which sends an HTTP request to a network binding / port. This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:SendToNetwork(idBinding, nPort, strData)

Parameter Description
num Binding ID of the network interface to send on
num Network port to send on
str Data to send out the specified network interface

Returns

None

Usage Note:

Data to be sent can contain NULL characters. NULL (‘\0’) is a valid character and Lua strings handle embedded NULL characters.

Example

C4:SendToNetwork(6001, 80, g_URLPacket)

SendToSerial

Simple function which sends the command out serial port on binding 1 and adds the \r terminator to the end of the command being sent. This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:SendToSerial(idBinding, strData)

Parameter Description
num Binding ID of the network interface to send on
str Data to send out the specified network interface

Returns

None

Usage Note:

Serial data to be sent can contain NULL characters. NULL (‘\0’) is a valid character and Lua strings handle embedded NULL characters

Example

function emit(strCommand)
   print("Emit: " .. strCommand)
   C4:SendToSerial("1", strCommand .. "\r")
end

SendWOL

Function that enables a Lua driver to broadcast a Wake-On-Lan magic packet.

Available from 2.10.0

Signature

C4:SendWOL(macAddress, port) 

Parameter Description
macAdress MAC address of the device.
num Optional. ID of the port the WOL magic packet is broadcast. If omitted, the WOL default port 9 is used.

Usage Note

The MAC address parameter can be formatted in one of two ways: Using a colon character (:) to delineate the six numeric values. For example: 00:0a:95:9d:68:16 or Using no delimiter: 000a959d6816

Returns

None

Usage Note:

Although using WOL can be useful for devices that do not provide a full network stack when powered off, there are some limitations: - Many network devices do not support Wake-On-Lan. - Requires that the MAC address of the destination device is known. - Does not work over WiFi. - Does not work beyond the local network (i.e., the Internet). - Does not provide confirmation that the intended device received the message.

Examples

C4:SendWOL("00:0a:95:9d:68:16")

In the example above, the port argument is omitted. The WOL magic packet is broadcast on port 9 which is default.

C4:SendWOL("000a959d6816", 42)

The example above broadcasts the WOL magic packet on port 42.

NetConnect

Function used to tell the system to make a connection (static or dynamic). Connections are created using the CreateNetworkConnection API. Further, port-specific configuration can be configured for a connection through the NetPortOptions API. This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:NetConnect(idBinding, nPort, strIPType,)

Parameter Description
num Binding ID of the network interface
num Network port to connect to. If NetPortOptions API is used with NetConnect, the remaining parameters are ignored.
str IP Type. Optional. TCP is assumed or UDP or MULTICAST

Returns

None

Examples

 C4:NetConnect(6001, 80, UDP)

NetDisconnect

Function called from DriverWorks driver to disconnect from a specific idBinding and nPort. This API should not be invoked during OnDriverInit.

Available from 1.6.0

Signature

C4:NetDisconnect(idBinding, nPort)

Parameter Description
num Binding ID of the network interface to disconnect from
num Network port.

Returns

None

NetPortOptions

Function to configure a connection's Port settings. The use of this API is contingent upon the use of the CreateNetworkConnection and NetConnect APIs. Connections are created using the CreateNetworkConnection API and Connections are made using the NetConnect API. This API should not be invoked during OnDriverInit.

Available from 2.8.0

Signature

C4:NetPortOptions(idBinding, nPort, strIPType,tPortParams)

Parameter Description
num Binding ID of the network interface to disconnect from
num Network port.
str Network Connection type. For example, TCP/SSL or UDP.
table lua table of Key/Value pairs that contain all of the parameters for the specific Port. These parameters include:

To the right is a sample tPortParams table using default values:

local tPortParams =  {
   AUTO_CONNECT = false,
   MONITOR_CONNECTION = true,
   KEEP_CONNECTION = true,
   KEEP_ALIVE = true,
   DELIMITER = "",
   CERTIFICATE = './client.pem',
   PRIVATE_KEY = './client_key.pem',
   MIRROR_UDP_PORT = false,
   PROTECTED = false,
   CACERTFILE = './root.pem',
   VERIFY_MODE = 'none',
   METHOD = 'tlsv1',
   SUPPRESS_CONNECTION_EVENTS = false
}

Usage Note

UDP Connection: The use of the mirror udp port parameter defaults to false. Setting this to true will use the value assigned in the nPort parameter of the NetPortOptions function (which is the destination port) as the source port value. Meaning that the data packets will be sent from and received on port values that are the same.

Returns

None

OnBindingValidate

The OnBindingValidate API supports validation by a driver before Director adds a new binding. This enables drivers to reject bindings that aren't valid due to some internal, dynamic state.

Available from 1.6.0

Signature

OnBindingValidate(idBinding, strClass) 

Parameter Description
num ID of the network binding being validated
str Class of the Binding.

OnConnectionStatusChanged

Function based on this return from the system used to process communication.

Available from 1.6.0

Signature

OnConnectionStatusChanged(idBinding, nPort, strStatus) 

Parameter Description
num ID of the network binding whose status has changed
num Port number whose status has changed
str Status: “OFFLINE” or “ONLINE”

Example

function OnConnectionStatusChanged(idBinding, nPort, strStatus)
  if (idBinding == 6001) then
    if (strStatus == "ONLINE") then
      -- Connect was successful.  Send URL packet.
      -- Other actions…
      -- Send 'queued' HTTP request to WeatherBug:
      C4:SendToNetwork(6001, 80, g_URLPacket)
    else
      -- OFFLINE... This means the receive buffer is full and ready to  
    process...
      -- Other actions…
    end
  end
end

OnNetworkBindingChanged

Function called by Director when a network connection has been addressed (‘identified’ on Network Connections Page) or unaddressed (‘disconnect’).

Available from 1.6.0

Signature

C4:OnNetworkBindingChanged(idBinding, bIsBound)

Parameter Description
num ID of the network binding whose status has changed
bool Whether the network binding has a bound address

Sample TCP Connection

To the right is a sample of a Driver's Connection XML. It shows the XML entries required for a static TCP type connection:

<connection>
    <id>6001</id>
    <connectionname>TCP</connectionname>
    <type>4</type>
    <hidden>True</hidden>
    <consumer>True</consumer>
    <classes>
        <class>
            <classname>TCP</classname>
            <ports>
                <port>
                    <number>6700</number>
                    <suppress_connection_events>True</suppress_connection_events>
                    <auto_connect>True</auto_connect>
                    <monitor_connection>True</monitor_connection>
                    <keep_connection>True</keep_connection>
                    <keep_alive>True</keep_alive>
                    <delimiter>0d0a</delimiter>
                </port>
            </ports>
        </class>
    </classes>
</connection>

In the example above we see the following XML elements:

In the example above, this is followed by the class section of the XML which contains the classname element. Note that the class name element is the same as the connectionname value.

This is followed by all of the port specific information for the connection. This is all that is required to configure a static, TCP connection for your driver.

If a dynamic connection is desired, the port information needs to reside within a table (tPortParams) inside the driver. The following is a sample of a the same connection as above, however it is created dynamically:

local tPortParams = {
   SUPPRESS_CONNECTION_EVENTS = true,
   AUTO_CONNECT = true,
   MONITOR_CONNECTION = true,
   KEEP_CONNECTION = true,
   KEEP_ALIVE = true,
   DELIMITER = "0d0a"
} 
C4:CreateNetworkConnection (6001, '192.168.1.100', "TCP")
C4:NetPortOptions(6001, 6700, "TCP", tPortParams)
C4:NetConnect(6001, 6700)

This connection is created using the CreateNetworkConnection API:

C4:CreateNetworkConnection (6001, '192.168.1.100', "TCP")

This connection's port parameters are sent using the NetPortOptions API:

C4:NetPortOptions(6001, 6700, "TCP", tPortParams)

Finally, the connection is made using the NetConnect API The use of the NetConnect API is required for the new connection to be made.

Sample SSL (Multi-Port) Connection

To the right is a sample of a Driver's Connection XML. It shows the XML entries required for a static SSL type connection using two ports (443 and 444):

<connection>
    <id>6001</id>
    <facing>6</facing>
    <connectionname>Hopper Control Connection</connectionname>
    <type>4</type>
    <consumer>True</consumer>
    <classes>
        <class>
            <classname>SSL</classname>
            <ports>
                <port>
                    <number>443</number>
                    <auto_connect>False</auto_connect>
                    <monitor_connection>False</monitor_connection>
                    <keep_connection>False</keep_connection>
                    <delimiter>0d</delimiter>
                    <certificate>./DISH.cert</certificate>
                    <private_key protected = "True">./DISH.cert</private_key>
                    <cacert>./DISH.cert</cacert>
                </port>
                <port>
                    <number>444</number>
                    <auto_connect>False</auto_connect>
                    <monitor_connection>False</monitor_connection>
                    <keep_connection>False</keep_connection>
                    <delimiter>0d</delimiter>
                    <certificate>./DISH.cert</certificate>
                    <private_key protected = "True">./DISH.cert</private_key>
                    <cacert>./DISH.cert</cacert>
                </port>
            </ports>
        </class>
    </classes>
</connection>

This connection using the first port is created using the CreateNetworkConnection API:

C4:CreateNetworkConnection (6001, '192.168.1.100', "SSL")

This connection's port parameters are sent using the NetPortOptions API:

C4:NetPortOptions(6001, 443, "SSL", tPortParams)

Finally, the connection is actually made using the NetConnect API. The use of the NectConnect API is required for the new connection to be made:

C4:NetConnect(6001, 443)

This connection using the second port is created using the CreateNetworkConnection API:

tPortParams["AUTO_CONNECT"] = false

This connection's port parameters are sent using the NetPortOptions API:

C4:NetPortOptions(6001, 444, "SSL", tPortParams)

Finally, the connection is made using the NetConnect API The use of the NectConnect API is required for the new connection to be made:

C4:NetConnect(6001, 444)

Server Socket Interface

Overview

This section describes the Server Sockets feature delivered in the 2.1.0 (and later) release of Control4’s System Software. The Server Sockets interface is a lightweight way for drivers to be to accept incoming socket connections, and process them easily.

CreateServer

Creates a Server Socket, that listens on port nPort, and sends messages to the driver upon receipt of the delimiter, strDelimiter (or upon timeout). This API should not be invoked during OnDriverInit.

Available from 2.10.0

Signature

C4:CreateServer(nPort, strDelimiter, bUseUDP) 

Parameter Description
num TCP Socket to listen for connections on. See note below for additional port information.
str Optional: Delimiter to separate messages. If no delimiter is specified, packets are delivered as they are received.
bool bUseUDP: When True, the server socket connection is a UDP server socket. The default is TCP.

Returns

None

Usage Note

The Listening socket may accept multiple connections, which can be active at the same time. See note below for additional port information.

Examples

Server Sockets Interface:

C4:CreateServer(5080, "\r\n")

Creates a Listening Socket Server on port 8080, with no delimiter (packets will be sent as received):

C4:CreateServer(8080)

To the right is an example that creates a UDP server socket connection:

C4:CreateServer(600, "", true)
function OnServerDataIn(nHandle, strData)
 print("OnServerDataIn" .. nHandle .. ": " .. strData)
end

Prior to operating system 2.9.0, it was not possible to specify a port in the C4:CreateServer API that was guaranteed to be safe. While the system could choose a port for you, the caller could not get that port to pass to clients for use. The end result was that driver writers would create drivers that would steal ports from Director or from each other.

Beginning with 2.9.0, callbacks have been modified or added (OnServerStatusChanged) where needed to allow getting the ephemeral port from the C4:CreateServer API and to get the IP address of a client connecting to the server created with C4:CreateServer. It is still possible to pass 0 for the port to have the OS select an available port for you. In the first example to the right, C4:CreateServer is specifying an ephemeral Port:


function run()
    dbg("run called")
    C4:CreateServer(0, '\n', false)
end

OnServerStatusChannged Callback to Get the Correct Port:

function OnServerStatusChanged(nPort, strStatus)
    print("OnServerStatusChanged port: " .. nPort .. " status: " .. strStatus)
end

Next, OnServerConnectionStatusChanged now Reports Client IP:

function OnServerConnectionStatusChanged(nHash, nPort, strStatus, strIP)
    print("OnServerConnectionStatusChanged hash: " .. nHash .. " port: " .. nPort .. " status: " .. strStatus .. " ip: " .. strIP)
end

The last example to the right shows executing the Lua code in an example driver with output to a console:

Property Changed: Driver Status
run called
Driver enabled
OnServerStatusChanged port: 53319 status: ONLINE
OnServerConnectionStatusChanged hash: 162938911 port: 53319 status: ONLINE ip: 192.168.200.100
OnServerDataIn hash: 162938911 data: lkasjdfl ip: 192.168.200.100

DestroyServer

Destroys any Server Sockets. This API should not be invoked during OnDriverInit.

Available from 2.10.0

Signature

C4:DestroyServer(nPort)

Parameter Description
num TCP Port to stop listening on (Should be the same as initially given)

Examples

This function stops listening on all ports:

C4:DestroyServer()

This function stops listening on port 8080:

C4:DestroyServer(8080)

OnServerConnectionStatusChanged

This function gets called when Server Socket connection status has changed.

Available from 2.10.0

Signature

OnServerConnectionStatusChanged(nHandle, nPort, strStatus) 

Parameter Description
num Server Socket handle. May be used to respond to this instance of a connection on the port, or to close this connection.
num Port for Socket Connection
str Status of the connection. Valid values include: ONLINE, OFFLINE

Returns

None

Example

This function prints the current status as it changes to the Lua Output window.

function OnServerConnectionStatusChanged(nHandle, nPort, strStatus)
  if (strStatus == "ONLINE") then
    print("Server Connection Established: " .. nHandle)
  else
    print("Server Connection Disconnected: " .. nHandle)
  end
end

OnServerDataIn

This function gets called when data is coming in on an open Server Socket.

Available from 2.10.0

Signature

OnServerDataIn(nHandle, strData, strclientAddress, strPort

Parameter Description
num Server Socket handle received in OnServerConnectionStatusChanged. Used to reply or disconnect this Server Socket.
str Data received
str IP of the remote client. For TCP servers this is the remote IP address of the connected client.
For UDP servers this is the IP address of the sender.
num Port of the remote client. For TCP servers this is the remote port number of the connected client.
For UDP servers this is the port number of the sender.

Returns

None

Example

This example prints the incoming data from an open Server Socket (assumes the data is ASCII printable)

function OnServerDataIn(nHandle, strData, strclientAddress, strPort)
  print("Received Data on Handle: " .. nHandle .. ": " .. strData .. ":"  strclientAddress  ": "  strPort))
end

ServerSend

This function is used to send data over an open Server Socket connection. This API should not be invoked during OnDriverInit.

Available from 2.10.0

Signature

C4:ServerSend(nHandle, strData)

Parameter Description
num Server Socket handle received in OnServerConnectionStatusChanged. Replies to or disconnects this same Server Socket.
str Data to be sent over the open Server Socket connection.

Returns

None

Example

This function shows sending data over a Server Socket:

C4:ServerSend(nHandle, strData)

ServerCloseClient

Close a previously open Server Socket connection. This API should not be invoked during OnDriverInit.

Available from 2.10.0

Signature

C4:ServerCloseClient(nHandle)

Parameter Description
num Server Socket handle received in OnServerConnectionStatusChanged.

Returns

None

Example

This function closes the server socket previously received.

C4:ServerCloseClient(nHandle)

Timer Interface

SetTimer

Creates and starts timer. This API should not be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:SetTimer(nDelay, fCallback, bRepeat)

Parameter Description
num Numeric value in milliseconds which is the desired timer delay. This value must be greater than 0.
func The function to be called when the timer fires.  The function signature for non-repeating timers is: function(timer)
bool bRepeat Optional parameter that, if provided and set to true, the timer will fire repeatedly until canceled.

The function signature for repeating timers is: function(oTimer, nSkips). timer is the same C4LuaTimer object that is returned from this function. skips (repeating timers only) indicates how many times director skipped calling the function. This can happen if the timer is set up to fire rapidly, but director was too busy to serve the timer in a timely manner.

For instance, if the timer was set up for 250ms and director was busy for 600ms before serving the timer, skips would be set to 2, indicating that it missed serving the timer twice since the last time it was served or since it was first started.

Returns

C4LuaTimer object with the following method(s):

oTimer:Cancel() - This function cancels the timer.

Usage Note

These timers do not trigger a call into the global OnTimerExpired function. To avoid potentially overwhelming Director with fast repeating timers, the C4:SetTimer() API will skip serving timers if it gets behind. If the timer handler cares, it will receive a second argument “skips” with the number of callbacks that director was not able to serve in a timely manner. This means that it is not guaranteed that if you set up a timer to fire 10 times a second, that your callback will actually get called back 10 times per second. It may get called fewer times than that if Director cannot keep up. If your driver needs to know, it can look at that new skips argument. This allows for much better scalability if some driver were to (accidentally) set a repeating timer with a very small value (e.g. 1ms, 10ms, 100ms). Prior to this change it was possible to permanently “lock up” director in such a case, which also could look like a memory leak as timers would get scheduled as a faster pace than were able to be served.

Examples

The first example to the right shows creating a Repeating Timer:

-- Repeating timer example (once a second):

     local cnt = 0
     local rt = C4:SetTimer(1000, function(timer, skips)
         -- timer is the same as what C4:SetTimer() returned
         print("Timer fired, skips: " .. skips)
         cnt = cnt + 1 + skips
         if (cnt > 9) then
             print("Canceling the timer now")
             timer:Cancel()
         end
     end, true)
     -- If you wish to cancel the timer at any time (even before it fired):
     --rt:Cancel()

The second example shows creating a Simple Timer:

-- Simple timer (once a second)

     local t = C4:SetTimer(1000, function(timer)
         -- timer is the same as what C4:SetTimer() returned
         print("Timer fired")
     end)
     -- If you wish to cancel the timer before it fired:
     --t:Cancel()

This function replaces the need to write awkward constructs involving the OnTimerExpired entry point and tracking timer handles such as shown in the final code sample:

g_cnt = 0
g_timer = C4:AddTimer(1, "SECONDS", true)

function OnTimerExpired(idTimer)
       if (idTimer == g_timer) then
              print("Timer fired")
              g_cnt = g_cnt + 1
       if (g_cnt > 9) then
              g_timer = C4:KillTimer(g_timer)
       end
end

GetTime

This API enables Lua drivers to retrieve the number of milliseconds since the epoch (1 January 1970 00:00:00 UT). See: https://en.wikipedia.org/wiki/Epoch_(computing)

This API was added in conjunction with O.S. 3.2.3.

Signature

C4:GetTime()

URL Interface

Overview

This API Interface replaces the following APIs:

C4:urlGet() C4:urlPost() C4:urlPut() C4:urlDelete() C4:urlCustom()

C4:url() utilizes a more flexible callback-based object interface. A call to this function returns a C4LuaUrl object that can be set up with various callback functions and options. Once set up, a call to its methods: Get(), Post(), Put(), Delete(), or Custom() initiates the transfer.

Available from 2.10.5

To the right is a basic example of how this interface can be used:

local t = C4:url()
 :OnDone(
  function(transfer, responses, errCode, errMsg)
   if (errCode == 0) then
    local lresp = responses[#responses]
    print("OnDone: transfer succeeded (" .. #responses .. " responses received), last response code: " .. lresp.code)
    for hdr,val in pairs(lresp.headers) do
     print("OnDone: " .. hdr .. " = " .. val)
    end
    print("OnDone: body of last response: " ..tostring(lresp.body))
   else
    if (errCode == -1) then
     print("OnDone: transfer was aborted")
    else
     print("OnDone: transfer failed with error " .. errCode .. ": " .. errMsg .. " (" .. #responses .. " responses completed)")
    end
   end
  end)
 :SetOptions({
  ["fail_on_error"] = false,
  ["timeout"] = 30,
  ["connect_timeout"] = 10
 })
 :Get("http://www.example.com", { ["Expect"] = "100-continue" })
print("scheduled url transfer with id " .. t:TicketId())

The C4LuaUrl Object that is returned supports the APIs defined in this section.

Cancel

Cancels a transfer that has been started by a call to the Get(), Post(), Put(), Delete(), or Custom() methods. The C4LuaUrl object cannot be re-used after canceling a transfer. A new instance will need to be created by a call to C4:url().

Available from 2.10.5

Signature

C4:Cancel()

Parameters

None

Returns

Returns a reference to itself.

Custom

Starts a HTTP transfer with a custom request method as specified by the method argument.

Available from 2.10.5

Signature

C4:Custom(url, method data, headers)

Parameter Description
url String of the URL to perform the PUT method on.
str String of the request method.
str String of the request body to be sent.
table A table of request headers and values to be sent.

Delete

Starts a HTTP DELETE transfer.

Available from 2.10.5

Signature

C4:Delete(url, data, headers)

Parameter Description
url String of the URL to perform the DELETE method on.
table A table of request headers and values to be sent.

Returns

A reference to itself.

Get

Starts a HTTP GET transfer.

Available from 2.10.5

Signature

C4:Get(url, headers)

Parameter Description
url String of the URL to perform the GET E method on.
table A table of request headers and values to be sent.

Returns

A reference to itself.

OnBody

Sets a callback function that will be called each time a response body has finished transferring. This function is called after the callback functions set by OnHeaders() and OnBodyChunk() but before the callback function set by OnDone(). Note that this method can only be called before a transfer was started.

Available from 2.10.5

Signature

C4:OnBody(func)

Parameter Description
func A callback function of type func (transfer, response). Returning true from this function aborts the transfer.

Usage Note

The transfer argument is the C4LuaUrl object that was created by the call to C4:url().

Returns

A reference to itself.

The response table contains the following keys:

Key Type Description
code num The status code of the response, e.g. 200, 404,...
headers table A table of all received headers and their value(s)
body str The entire response body as a string. This key is absent if a callback was set with OnBodyChunk().

The same response table will be passed to the callback set by OnDone(). Any modifications to this table will persist, but not affect the transfer in any way.

OnBodychunk

Sets a callback function that will be called each time a chunk of the response body has transferred. This does not necessarily correlate to chunks in the context of the HTTP "chunked" transfer encoding. This function may be called multiple times for each response, following the callback function set by OnHeaders() and before the callback function set by OnBody() and OnDone(). Note that this method can only be called before a transfer was started. This callback function is not needed for most use-cases.

Available from 2.10.5

Signature

C4:OnBodyChunk(func)

Parameter Description
func A callback function of type func (transfer, response, chunk). Returning true from this function aborts the transfer.

Usage Note

The transfer argument is the C4LuaUrl object that was created by the call to C4:url().

Returns

A reference to itself.

The response table contains the following keys:

Key Type Description
code num The status code of the response, e.g. 200, 404,...
headers table A table of all received headers and their value(s)

The same response table will be passed to the callbacks set by OnBody() and OnDone(). Any modifications to this table will persist, but not affect the transfer in any way.

The chunk argument is a string of the received chunk of the response body. By using the OnBodyChunk() callback, it is up to the driver process and/or store the data as needed. In this case, the interface does not aggregate the response body, and it is not stored in the body key of the response table.

OnDone

Sets a callback function that will be called when the entire transfer succeeded or failed. It is only called once at the end of the entire transfer regardless of how many responses have been received. Note that this method can only be called before a transfer was started.

Available from 2.10.5

Signature

C4:OnDone(func)

PArameter Description
func A callback function of type func(transfer, responses, errCode, errMsg).

Usage Note

The transfer argument is the C4LuaUrl object that was created by the call to C4:url(). The responses argument receives a table (array) of the response tables in the order that they were received. These response tables are the same ones that were passed to the callback functions set by OnHeaders(), OnBody(), and OnBodyChunk().

If the transfer succeeded, the errCode argument will be 0 and errMsg will be nil. If the transfer was aborted by one of the callback functions the errCode argument will be -1. Otherwise, errCode will hold a number with an error code and the errMsg argument will contain a string with details.

Once the transfer has completed (or failed), the C4LuaUrl object cannot be re-used. A new instance will need to be created by a call to C4:url().

Returns

A reference to itself.

OnHeaders

Sets a callback function that will be called each time all of the headers of a response have been received but, before the response body has been received. This function may be called multiple times, e.g. due to redirects. Note that this method can only be called before a transfer was started.

Available from 2.10.5

Signature

C4:OnHeaders(func)

Parameter Description
func A callback function of type func (transfer, response, chunk). Returning true from this function aborts the transfer.

Usage Note

The transfer argument is the C4LuaUrl object that was created by the call to C4:url().

Returns

A reference to itself.

The response table contains the following keys:

Key Type Description
code num The status code of the response, e.g. 200, 404,...
headers table A table of all received headers and their value(s)

The same response table will be passed to the callbacks set by the following:

OnBody()

OnBodyChunk()

OnDone()

Any modifications to this table will persist but not affect the transfer in any way.

Example

OnHeaders(
    function(transfer, response)
        -- transfer is the object returned by C4:url()
        print("OnHeaders: status code: " .. response.code)
        for hdr,val in pairs(resp.headers) do
            print("OnHeaders: header " .. hdr .. " = " .. val)
        end
        -- return true -- to abort the transfer
    end

Post

Starts a HTTP POST transfer.

Available from 2.10.5

Signature

C4:Post(url, data, headers 

Parameter Description
url String of the URL to perform the POST method on.
str String of the request body to be sent.
table A table of request headers and values to be sent.

Returns

A reference to itself.

Put

Starts a HTTP POST transfer.

Available from 3.0.0

Signature

C4:Put (url, data, headers 

Parameter Description
url String of the URL to perform the POST method on.
str String of the request body to be sent.
table A table of request headers and values to be sent.

Returns

A reference to itself.

Usage Note

This API should only be used in conjunction with Control4 OS 3 and later.

SetOption

Sets one option specified by name to value. Note that this method can only be called before a transfer was started.

Available from 2.10.5

Signature

C4:SetOption(name, value)

Parameter Description
str String value of the name of the parameter.
bool Value - Boolean value (number or string) of the parameter.

Below is a list of valid option names and their values

fail\_on\_error boolean:

Defaults to true. If any response returns with an error code, the entire transfer fails with an error. If set to false, allows the driver to e.g. read the HTTP response body of a 403 error response.

timeout number:

In seconds. Defaults to 300 or whatever value was set through C4:urlSetTimeout(). This is how many seconds, total, the entire transfer is allowed to take.

connect\_timeout number:

In seconds. Defaults to 5. This is how many seconds it is allowed to take to establish the connection to the host.

ssl\_verify\_host boolean:

Defaults to true. Verify the host against the system's CA bundle when using the https protocol.

ssl\_verify\_peer boolean:

Defaults to true. Verify the peer against the system's CA bundle when using the https protocol.

ssl\_cabundle string:

A filename relative to the .c4z that specifies a CA bundle to use instead of the system's. It is not recommended to use this option except for very special use cases because CA bundles require regular updates.

ssl\_cert ssl_cert:

A filename relative to the .c4z that specifies a SSL client certificate to use for authentication to the host.

ssl\_cert\_type string:

Defaults to "PEM". The format of the SSL certificate that the file specified by the "ssl_cert" option is in. Valid values are: "PEM" (default), "DER", "P12".

ssl\_key string:

A filename relative to the .c4z that specifies the private key for the client certificate specified by the "ssl_cert" option.

ssl\_passwd string:

If the private key specified by the "ssl_key" option is encrypted, this option specifies the password.

ssl\_cacerts table:

A table of filenames relative to the .c4z that specify additional certificates to be added to the CA bundle used to verify the host and/or peer. This allows e.g. extending the CA bundle to be able to verify against self-signed or company-signed certificates.

Returns

A reference to itself.

SetOptions

This API is similar to the SetOption() method, but allows the driver to pass in a table of options and their values. Note that this method can only be called before a transfer was started.

Available from 2.10.5

Signature

C4:SetOptions(options)

Parameter Description
table Table of options and their values:

Below is a list of valid option names and their values

response_headers_duplicates boolean:

If set to true and duplicate response headers are received, the tHeader table will have an array of string values for this header. If set to false (default) and duplicate response headers are received, only the last header received will be saved to the tHeader table. This option defaults to false.

cookies_enable boolean:

If set to true, enables the use of cookies.  If the cookies_use_jar option is set to true, this causes cookies to be stored in the driver's cookie jar. If set to false (default) and a Set-Cookie header is received, the cookie will neither be stored in the driver's cookie jar, nor will it be used with any redirect request that may automatically be performed. This option defaults to false.

cookies_use_jar boolean:

If set to true (default), uses cookies in the driver's cookie jar. If set to false, this transfer does not use any cookies that may be stored in the driver's cookie jar. This option defaults to true.

cookies_save_to_jar boolean:

If set to true (default), saves any new cookies to the driver's cookie jar. This may also delete expired cookies from the cookie jar. If set to false, any cookies received from this transfer will not be saved to the jar. This option defaults to true.

cookies_clear_session boolean:

If set to true, clears any "session" cookies (cookies with no expiration time) from this transfer prior to making the request.  This does not remove them from the driver's cookie jar, but if the cookies_save_to_jar"option is set to true, it will remove them from the cookie jar once the transfer completes. If set to false (default), session cookies are used for this transfer. This option defaults to false.

Returns

A reference to itself.

TicketId

Returns the Ticket ID (a number) of a running transfer. If the transfer is not running, the value 0 is returned.

Available from 2.10.5

Signature

C4:TicketId() 

Parameters

None

Returns

Value Description
num A number identifying the running transfer, otherwise 0.

Variable Interface

AddVariable

Function called from a DriverWorks driver to create a Control4 variable for the driver. Note that Variables need to be added in OnDriverInit. Programming attached to variables added after OnDriverInit may not work properly on Director restart.

Available from 1.6.0.

Signature

C4:AddVariable(identifier, strValue, strVarType, [bReadOnly], [bHidden]) 

Parameter Description
identifier A string or number that uniquely identifies the variable to be added. If a number it must be greater than zero.
strValue String. If strVartype equals “BOOL” then “1” = true, “0” = false. Note, that valid values are 0 and 1 and need to be passed as strings.
strVarType String. See variable types below.
bReadOnly Boolean. ReadOnly: Optional, defaults to FALSE
bHidden Boolean. Hidden: Optional, defaults to FALSE. A flag indicating whether the variable is hidden.

Usage Notes

There is no limit to the string length for a variable created using AddVariable. This can be done inside a driver programmatically or within Composer Pro.

Valid variable types are:

While the following variable type can be successfully passed within the API, functionality will be supported in a future release.

Returns

Value Description
True Indicates that the variable was added successfully.
ID ID of the variable that was added.
False Indicates that the variable could not be added. Failure generally occurs when either the name or ID is not unique.

Usage Note

If the variable ID is identified by number, then this matches the value specified in the identifier argument.

Usage Note

Variables should always be added in the same order. Control4 Composer programming is based on VariableID’s, which are allocated in order during AddVariable calls. In other words, if you add a set of variables then later delete them and re-add different variables or in a different order, Composer programming will be incorrect.

When adding a variable by name (i.e.,identifier parameter is a string), the ID of the variable is computed. The default value of the first variable added by name is 1001, then 1002 for the second variable, and so forth. If the computed ID matches that of an existing variable, then the next available unique ID in the sequence is selected. For example, consider the following code to the right:

local result, id = C4:AddVariable(1002, "Foo", "STRING")
print(result, id)
 
result, id = C4:AddVariable("Biz", "Baz", "STRING")
print(result, id)
 
result, id = C4:AddVariable("Yaz", "Yap", "STRING")
print(result, id)

Executing this code prints the following:

true    1002
true    1001
true    1003

Note that when adding the third variable ("yaz"), the computed ID is 1003. This occurs because on line 1 we added a variable with ID 1002. As a result, the next available ID is 1003.

When adding a variable by number (i.e., identifier is a number), the name of the variable is computed to be a string representation of the specified ID. Note that the computed name must be unique among all existing variables. The following code illustrates this problem:

local result, id = C4:AddVariable("1001", "Foo", "STRING")
print(result, id)

result, id = C4:AddVariable(1001, "Bar", "STRING")
print(result, id)

Executing this code prints the following:
true,    1001
false

The second call to C4:AddVariable fails because on line 1 we added a variable with name "1001".

DeleteVariable

Function called from a DriverWorks driver to delete a Control4 variable for the driver. This API should not be invoked during OnDriverInit

Available from 1.6.0.

Signature

C4:DeleteVariable(identifier) 

Parameter Description
str/num A str or num that uniquely identifies the variable to be deleted.

Usage Note

If string is used, then the variable is located by name. If the value is a number, then the variable is located by ID. In addition, the value of a numeric identifier must be | greater than zero.

Returns

None

Example

Deletes the device variable named Driver Variable" from the Control4 system

C4:DeleteVariable("Driver Variable")

DriverWorks Variable Table

The Lua Table ‘Variables’ contains the current value of this driver’s variables. Although you can read directly from this table, to change the value of a device variable, you should use: C4:SetVariable(strName, strValue)

Available from 1.6.0.

Examples

Use Variables in a comparison:
if (Variables["Power State"] == "OFF") then
    C4:SendToSerial(idSerialBinding, "ON")
    C4:SetVariable("Power State", "ON")
end

Print out all Variables:

for VariableName, VariableValue in pairs(Variables) do 
    print(VariableName, VariableValue) 
end

GetVariable

Function called by a DriverWorks driver to get the value of a variable. This API should not be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:GetVariable(idDevice, idVariable)

Parameter Description
num Device ID of the device that owns the specified variable
num Variable ID of the specified variable

Returns

Value Description
str String Value of the requested variable, nil if not found.

Usage Note

User Variables belong to the Variable Agent, with a DeviceID of 100001.

Examples

Gets and prints the value of the HVAC mode and temperature variables of a Control4 Thermostat registered in the project as Device ID 84:

print(C4:GetVariable(84, 1000))
print(C4:GetVariable(84, 1003))

Gets and prints the User Variable registered with the project as variable 209:

print(C4:GetVariable(100001, 209))

GetDeviceVariable

Function called by a DriverWorks driver to get the value of another device's variable. This API should not be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:GetDeviceVariable(idDevice, idVariable)

Parameter Description
num Device ID of the device that owns the specified variable
num Variable ID of the specified variable

Returns

Returns Description
str String Value of the requested variable, nil if not found.

Usage Note

User Variables belong to the Variable Agent, with a DeviceID of 100001.

Examples

Gets and prints the value of the HVAC mode and temperature variables of a Control4 Thermostat registered in the project as Device ID 84:

print(C4:GetDeviceVariable(84, 1000))
print(C4:GetDeviceVariable(84, 1003))

SetDeviceVariable

Function called from a DriverWorks driver to set the value of another driver or device's variable. This API should not be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:SetDeviceVariable(DeviceID, variableID, strValue)

Parameter Description
num ID value of the device
num ID of variable to set
str Value to set variable

Returns

None

Usage Note

User Variables belong to the Variable Agent, with a DeviceID of 100001.

Examples

Sets the device variable value of the device with ID of 10 and variable ID of 1005 to 90:

C4:SetDeviceVariable(10, 1005, 90)

SetVariable

Function called from a DriverWorks driver to set the value of the current driver's variable. This API should not be invoked during OnDriverInit

Available from 1.6.0.

Signature

C4:SetVariable(identifier, strValue)

Parameter Description
identifier A string or number that uniquely identifies the variable to be added. If the identifier value is a string, then the variable is located by name. If the value is a number, then the variable is located by ID. In addition, the value of any numeric identifier must be greater than zero.
strValue The value passed here is variable type dependent. See supported variable types in the AddVariable API.

Returns

None

Examples

Sets the value of the device variable named “Driver Variable” to 90:

C4:SetVariable("Driver Variable", 90)

OnVariableChanged

Function called by Director when one of this driver’s variables’ values is changed.

Available from 1.6.0.

Signature

C4:OnVariableChanged(strName)

Parameter Description
str Name of variable that has changed

Returns

None

Usage Notes

OnVariableChanged is NOT called on a driver when it changes its own variable’s value. The value of the variable that has changed can be found with: Variables strName

Example

This simple function prints to the Lua Output window in Composer when any variable on that device changes and includes the variable name and value.

function OnVariableChanged(strName)
  print("Variable value changed - variable named: " .. strName)
  print(" ... new value is: " .. Variables[strName])
end

OnWatchedVariableChanged

Function called by Director when a Control4 variable changes value.

Available from 1.6.0.

Signature

C4:OnWatchedVariableChanged(idDevice, idVariable, strValue)

Parameter Description
num Device ID of the device that owns the changed variable
num Variable ID of the changed variable
str New value of variable that has changed

Returns

None

Usage Note

Watched variables are variables that belong to other devices in the system, not variables that necessarily belong to a DriverWorks driver.

Example

This example function prints the value of the device ID, variable ID, and variable value when any watched variable changes:

function OnWatchedVariableChanged(idDevice, idVariable, strValue)
  print("Variable changed...")
  print("  device: " .. idDevice)
  print("  variable: " .. idVariable)
  print("  value: " .. strValue)
  print("-----------")
end

RegisterVariableListener

Function called from a DriverWorks driver to set a listener on a particular device’s variable. When a listener is set on a variable, whenever the variable changes, the Lua OnWatchedVariableChanged call is called.

Available from 1.6.0.

Signature

C4:RegisterVariableListener(idDevice, idVariable) 

Parameter Description
num Device ID of the device that owns the changed variable
num Variable ID of the changed variable

Returns

None

Usage Notes

User Variables belong to the Variable Agent, with a DeviceID of 100001. The OnWatchedVariableChanged function will be called immediately after the listener is successfully set.

This API will fail if the variable does not exist.

Example

This example watches the value of the temperature and HVAC mode variables on a Control4 Thermostat registered with the system as device 84. It also registers to watch for changes to the user variable 209:

C4:UnregisterVariableListener(84, 1000)
C4:UnregisterVariableListener(84, 1003) C4:UnregisterVariableListener(100001, 209)
C4:RegisterVariableListener(84, 1000)
C4:RegisterVariableListener(84, 1003)
C4:RegisterVariableListener(100001, 209)

function OnWatchedVariableChanged(idDevice, idVariable, strValue)
  print("Variable changed...")
  print("  device: " .. idDevice)
  print("  variable: " .. idVariable)
  print("  value: " .. strValue)
  print("-----------")
end

UnRegisterAllVariableListeners

This API unregisters any/all previously registered variable listeners. It takes no arguments and returns nothing.

Signature

C4:UnregisterAllVariableListeners()

UnregisterVariableListener

Function called from DriverWorks driver to remove a listener on a particular device's variable. Variable changes for the particular Device's Variable will no longer be reported. This API will not work if a variable has not been registered, added or does not exist.

Available from 1.6.0.

Signature

C4:UnregisterVariableListener(idDevice, idVariable)

Parameter Description
num Device ID of the device that owns the requested variable
num Variable ID of the requested variable

Returns

None

Usage Notes

User Variables belong to the Variable Agent, with a DeviceID of 100001.T

Example

This stops the system from reporting variable value changes for the specified device and variables:

C4:UnregisterVariableListener(84, 1000)
C4:UnregisterVariableListener(84, 1003)
C4:RegisterVariableListener(100001, 209

List of Room Variables

To the right is an example of subscribing to the currently selected device and the navigator variables of the room.

Variable_Current_Selected_Device = VARIABLE_ID_START,
Variable_Current_Audio_Device,
Variable_Current_Video_Device,
Variable_Audio_Volume_Device,
Variable_Video_Volume_Device,
Variable_Current_Media,
Variable_Current_Media_Type,
Variable_Current_Audio_Path,
Variable_Current_Video_Path,
Variable_Current_Video_Audio_Path,
Variable_Power_State,
Variable_Current_Volume,
Variable_Temperature_ID,
Variable_Temperature_Control_ID,
Variable_Security_ID,
Variable_Current_Volume_Device,
Variable_Has_Discrete_Volume,
Variable_Has_Discrete_Mute,
Variable_Is_Muted,
Variable_In_Navigation,
Variable_Use_Default_Volumes,
Variable_Default_Audio_Volume,
Variable_Default_Video_Volume,
Variable_Volume_Linked,
Variable_Linked_Room_List,
Variable_Mute_Linked,
Variable_RoomOff_Linked,
Variable_Selections_Linked,
Variable_Current_Linked_MediaID,
Variable_Room_Hidden,
Variable_Linked,
Variable_Media_Info,
Variable_Last_Device_Group,
Variable_Available_Cameras,
Variable_Pools,
Variable_Scene_Is_Discrete_Volume,

Example

roomId = C4:RoomGetId()
-- be notified when the currently selected device is changed
C4:RegisterVariableListener(roomId, 1000)
-- be notified when we are in nav or not
C4:RegisterVariableListener(roomId, 1019)


function OnWatchedVariableChanged(idDevice, idVariable, strValue) 
  print("Variable changed...") 
  print("  device: " .. idDevice) 
  print("  variable: " .. idVariable) 
  print("  value: " .. strValue) 
  print("-----------") 
end 


    C4:SendToDevice(roomId, "CONTROL4", tParams) 
    C4:SendToDevice(roomId, "EXIT_NAVIGATION", tParams) 
-- Example Output

Variable changed...
device: 5
variable: 1000
value: 7

-----------

Variable changed...
device: 5
variable: 1019
value: 1

-----------

Variable changed...
device: 5
variable: 1019
value: 0

Web Service Interface

Overview

Webservice Authentication using Lua

Control4 drivers have the ability to perform Basic and Digest authentication with a web service using any of the “*url”*APIs within this Interface. Authentication is achieved by passing the username and password within the string parameter used by each of the APIs.

Note: Starting with O.S 3, sample drivers are being delivered with the DriverWorks SDK. Included in the sample driver delivery is the generic-http driver which demonstrates how to do basic C4:url calls. The sample driver can be found at the root level of the SDK or DriverWorks SDK/Samples.

Also included in the Samples directory is an example websockets client driver.

ReceivedAsync

This function is used in conjunction with urlGet and urlPost. It handles the data contained in the data ticket. As soon as data is returned from getUrl, Director will call this in the Lua code. This API should not be invoked during OnDriverInit.

Available from 1.6.0.

Signature

function ReceivedAsync(ticketId, strData, responseCode, tHeaders, strError)

Parameters

None

Returns

Parameter Description
num Number representing the data ticket
str String representing the data contained in the ticket
code Response code
table Lua table of response headers
str String representing the error content

Example

function ReceivedAsync(ticketId, strData)
  callType = g_ticketToTypeMap[ticketId]
  --print("ra - ct = " .. callType .. " id is " .. ticketId .. " data is<< " .. strData .. " >>")
  if (callType == "root") then
        g_shoutCastHtmlParsed = parsestr(strData)
  elseif (callType == "playlist") then
                stationUrl = GetStationUrlFromHtml(strData)
            if (stationUrl) then
                   print("Adding station " .. stationUrl)
                         AddStationToDb(stationUrl, ticketId)
         else
                -- must have been a genre item they clicked on
            genreTable = parsestr(strData)
            ShowSubGenres("Add Genre", genreTable)
                end
  else
                print("ReceivedAsync called with unexpected id of " .. ticketId) -- ..  and data of " .. strData)
  end
end

urlCancel

Function to cancel an ongoing transfer. Note that if a transfer is canceled, neither the ReceivedAsync() entry point nor the callback function specified in the C4:url call will be called.  Also, the ticketId is only valid from the point the C4:url function is called until either the ReceivedAsync() entry point or the callback function was called. A call to C4:urlCancel() will also invalidate that ticketed. This API should not be invoked during OnDriverInit

Available from 2.7.0.

Signature

C4:urlCancel(ticketId)

Parameter Description
num Number representing the ticket ID value.

Returns

Parameter Description
bool True if the specified transfer was canceled.

Usage Note

Control4 Web Service APIs, specifically those beginning with C4:url, send the following default Headers with the HTTP(s) request:

Host: <DNS name or IP of server>,
Accept: "/",
Accept-Encoding: "deflate, gzip"
Connection: "close", is suggested and 

Example

To the right is an example that does a C4:urlGet() and waits only a maximum of one second for a response before canceling:

local transferTicketId, timer
transferTicketId = C4:urlGet("http://www.example.com", {}, true, function(ticketId, strData, responseCode, tHeaders, strError)
        if (timer ~= nil) then
                  -- Cancel the timer if the transfer completed first
                  timer:Cancel()
                  timer = nil
                end
               
                if (strError == nil) then
                         print("C4:urlGet() completed with response code " .. tostring(responseCode))
                else
                         print("C4:urlGet() failed with error: " .. strError)
                end
end)
timer = C4:SetTimer(1000, function(tmr)
        local success = C4:urlCancel(transferTicketId)
        print("C4:urlGet() took too long, C4:urlCancel() returned " .. tostring(success))
end)
 
--[[
   Example output:
     If the timer expired before the transfer completed:
        C4:urlGet() took too long, C4:urlCancel() returned true
 
     If the transfer completed before the timer expired:
        C4:urlGet() completed with response code 200
--]]

urlCancelAll

This method cancels all ongoing transfers and returns an array with the ticket ids of the transfers that were canceled. This API should not be invoked during OnDriverInit.

Available from 2.8.1.

Signature

C4:urlCancelAll()

Parameters

None

Returns

None

Usage Note

Control4 Web Service APIs, specifically those beginning with C4:url, send the following default Headers with the HTTP(s) request:

Host: <DNS name or IP of server>,
Accept: "/",
Accept-Encoding: "deflate, gzip"
Connection: "close"

It is recommended that these Headers NOT be overwritten.

Note that a user-agent string is not included in the default Headers. However, including one within a driver is suggested as it makes diagnostics easier for servers.

urlClearCookies

Function to clear all cookies from a driver's cookie jar.

Available from 2.9.0.

Signature

C4:urlClearCookies() 

Parameters

None

Returns

Value Description
num The number of cookies that were removed.

Usage Note

Control4 Web Service APIs, specifically those beginning with C4:url, send the following default Headers with the HTTP(s) request:

Host: <DNS name or IP of server>,
Accept: "/",
Accept-Encoding: "deflate, gzip"
Connection: "close", is suggested and 

It is recommend that these Headers NOT be overwritten.

Note that a user-agent string is not included in the default Headers. However, including one within a driver is suggested as it makes diagnostics easier for servers.

urlClearSessionCookies

Function to clear all session cookies from a driver's cookie jar.

Available from 2.9.0.

Signature

C4:urlClearSessionCookies()

Parameters

None

Returns

Value Description
num The number of session cookies (cookies with no expiration time) that were removed

Usage Note

Control4 Web Service APIs, specifically those beginning with C4:url, send the following default Headers with the HTTP(s) request:

Host: <DNS name or IP of server>,
Accept: "/",
Accept-Encoding: "deflate, gzip"
Connection: "close", is suggested and 

It is recommend that these Headers NOT be overwritten.

Note that a user-agent string is not included in the default Headers. However, including one within a driver is suggested as it makes diagnostics easier for servers.

urlGetCookies

Function to retrieve cookies from the driver's cookie jar filtered by a specific domain.

Available from 2.9.0.

Signature

C4:urlGetCookies (domain)

Parameter Description
str Optional. A specific domain.

Returns

Value Description
table Table of a map of domain names to a map of cookie names to cookie table objects.

Usage Note

Each cookie table has the following fields defined:

Usage Note

Control4 Web Service APIs, specifically those beginning with C4:url, send the following default Headers with the HTTP(s) request:

Host: <DNS name or IP of server>,
Accept: "/",
Accept-Encoding: "deflate, gzip"
Connection: "close", is suggested and 

It is recommend that these Headers NOT be overwritten.

Note that a user-agent string is not included in the default Headers. However, including one within a driver is suggested as it makes diagnostics easier for servers.

Example

for domain,cookies in pairs(C4:urlGetCookies()) do
    for name,cookie in pairs(cookies) do
        print("cookie[" .. domain .. "][" .. name .. "]: path: " .. cookie.path .. " value: " .. cookie.value)
    end
end

urlGetCookiesForDomain

Function to retrieve cookies from the driver's cookie jar filtered by a specific domain.

Available from 2.9.0.

Signature

C4:urlGetCookiesForDomain (domain)

Parameter Description
str Optional. A specific domain.

Returns

Value Description
table Table of a map of domain names to a map of cookie names to cookie table objects. 

Usage Note

Each cookie table has the following fields defined:

Usage Note

Control4 Web Service APIs, specifically those beginning with C4:url, send the following default Headers with the HTTP(s) request:

Host: <DNS name or IP of server>,
Accept: "/",
Accept-Encoding: "deflate, gzip"
Connection: "close", is suggested and 

It is recommend that these Headers NOT be overwritten.

Note that a user-agent string is not included in the default Headers. However, including one within a driver is suggested as it makes diagnostics easier for servers.

Example

for name,cookie in pairs(C4:urlGetCookiesForDomain("example.com")) do
    print("cookie[" .. cookie.domain .. "][" .. name .. "]: path: " .. cookie.path .. " value: " .. cookie.value)
end

urlGetOption

Function to retrieve cookies from the driver's cookie jar filtered by a specific domain.

Available from 2.9.0.

Signature

C4:urlGetOption (option)

Parameter Description
num Returns the number of concurrent transfers allowed per hostbool
bool Returns whether HTTP pipelining is enabled.

Returns

Value of the option parameter passed

Usage Note

Control4 Web Service APIs, specifically those beginning with C4:url, send the following default Headers with the HTTP(s) request:

Host: <DNS name or IP of server>,
Accept: "/",
Accept-Encoding: "deflate, gzip"
Connection: "close"

It is recommend that these Headers NOT be overwritten.

Note that a user-agent string is not included in the default Headers. However, including one within a driver is suggested as it makes diagnostics easier for servers.

urlGetTickets

This method returns an array with the ticket ids of all ongoing transfers. This API should not be invoked during OnDriverInit.

Available from 2.8.1.

Signature

C4:urlGetTickets()

Parameter

None

Returns

Ticket IDs

Usage Note

Control4 Web Service APIs, specifically those beginning with C4:url, send the following default Headers with the HTTP(s) request:

Host: <DNS name or IP of server>,
Accept: "/",
Accept-Encoding: "deflate, gzip"
Connection: "close", is suggested and 

It is recommend that these Headers NOT be overwritten.

Note that a user-agent string is not included in the default Headers. However, including one within a driver is suggested as it makes diagnostics easier for servers.

urlSetOption

This function changes the option specified in the option argument to the value provided. The options and their respective value parameters can be one of the two defined in the signature section below. This API should not be invoked during OnDriverInit.

NOTE: These options apply to both the 'legacy' C4:urlGet / C4:urlPut / C4:urlPost commands, as well as the newer C4:url() functionality.

Available from 2.8.1.

Signature

C4:urlSetOption(option, value)

There are 2 supported options: max_host_connections, and 'pipelining'.

max_host_connections parameter:

Parameter Description
num Number of concurrent transfers allowed per host. Defaults to 1. NOTE: This must be a number from 1-5. 5 is the maximum number of connections allowed. Any numbers outside of this range will not be honored, and the current value will be kept. 

pipelining parameter:

Parameter Description
bool pipelining. Sets whether HTTP pipelining should be enabled.

Usage Notes

Note that if the concurrent transfers value is being changed to anything other than 1, the "pipelining" option will automatically get disabled.

Note that If the pipelining boolean is being changed to true, the max_host_connections option will automatically be set. Changing this option will not have any effect until there are no active transfers running. Also, it will not apply to new transfers created until then. Once all transfers are completed, this setting will apply to any transfers created from that point on.  You can use the C4:urlCancelAll() method to cancel all transfers prior to setting this option, or you can use the C4:urlGetTickets() method to determine whether any transfers are currently pending.

Returns

None

Examples

C4:urlSetOption("max_host_connections", 1)

C4:urlSetOption("pipelining", true)

urlSetProxy

This function is to set server related security information that may be needed in future related url calls. This API should not be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:urlSetProxy ()

Parameter Description
str url to be used for supplied credentials bool
num port corresponding to the url
str  username to be used for the url
str password to be used for the urlfailOnHttpError (boolean) - True/False. Defaults to True.

Returns

None

Usage Note

Control4 Web Service APIs, specifically those beginning with C4:url, send the following default Headers with the HTTP(s) request:

Host: <DNS name or IP of server>,
Accept: "/",
Accept-Encoding: "deflate, gzip"
Connection: "close", is suggested and 

It is recommend that these Headers NOT be overwritten. Note that a user-agent string is not included in the default Headers. However, including one within a driver is suggested as it makes diagnostics easier for servers.

Examples

C4:urlSetProxy("www.mywebsite.com", 8080, "me", "mypassword")

urlSetTimeout

This function is to set a maximum time value (in seconds) for a transfer operation to take place before a server time out occurs. The value passed in this API is dependent on driver/Director performance. For example, setting this value too low could result in a timeout occurring too quickly resulting in messages missed. Setting it too high could result in lag time and poor user experience. Control4 recommends an initial setting of 20 seconds and adjusting as needed. This API should not be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:urlSetTimeout(SECONDS) 

Parameter Description
int  number of seconds allowed

Returns

None

Usage Notes

Starting with the release of OS 2.9.0, urlSetTimeout is optional as a driver no longer has to make this call explicitly. As of 2.9.0, Control4 imposes a 300 second overall timeout to all web requests by default.  A driver may however override this and call C4:urlSetTimeout() to revert back to the behavior described above. 

Control4 Web Service APIs, specifically those beginning with C4:url, send the following default Headers with the HTTP(s) request:

Host: <DNS name or IP of server>,
Accept: "/",
Accept-Encoding: "deflate, gzip"
Connection: "close", is suggested and 

It is recommend that these Headers NOT be overwritten. Note that a user-agent string is not included in the default Headers. However, including one within a driver is suggested as it makes diagnostics easier for servers.

Example

C4:urlSetTimeout(20)

Zigbee Interface

Overview

DriverWorks and Zigbee Functionality

DriverWorks support for Zigbee functionality was originally delivered in release 1.6.1. This section has been included to provide information to Control 4 partners already using the Zigbee SDK. This information will support the development of DriverWorks Zigbee functionality so that partners using the Zigbee SDK can integrate into the Control 4 system.

Functionality provided in support of Zigbee functionality currently includes:

Updating Zigbee Device firmware Using DriverWorks

The ability to use DriverWorks drivers to update firmware on ZigBee devices has been implemented using two features:

  1. Support of encoded BLOB data (firmware) within the driver file
  2. Functions to handle device requests and delivery of the firmware data.

Encoded BLOB Data in the Driver File 

DriverWorks supports the ability to store binary firmware data within the driver file. This data must be Base64 encoded. The encoded firmware data string information should reside at the beginning of the driver file as seen in the example to the right:

<devicedata>
 <copyright>Copyright 2019 Control4 Corporation. All rights reserved.</copyright>
   <largeblobs>
    <largeblob name="Blob1">VGhpcyBpcyBOaGUgRmlyc3QgQkxPQiENCg==</largeblob>
   <largeblobname="Blob2">AAECAwQFBgclCQoLDA0ODwABAgMEBQYHCAkKCwwNDg8=</largeblob>
  </largeblobs>
 <config>

When ZigBee devices come on-line they can validate firmware versions with Director. If an update is available, the data is sent accordingly to the device. Drivers that wish to update their device’s firmware should do it in a sequential manner. The functions delivered in this SDK support this. It is possible to place the BLOB data in the Lua section of the driver. However, this requires a copy of the firmware data within every loaded driver used by the device. For example, if 15 devices use the driver, it will be necessary to maintain 15 copies of the firmware update data loaded in memory.

Firmware Request Functions

When a device requests a firmware update (the version of the firmware on the device is older than the firmware the driver has), the driver should request a 'reflash lock' via RequestRefreshLock. This allows the driver to ensure that it is the only driver updating a device at any time. This is required so that Director can manage multiple Zigbee drivers so that only one driver will be allowed to update at a time. This ensures that device firmware updates don't overload the zigbee network.

The OnReflashLockGranted function is called by Director when the driver has permission to update the firmware on the device. This function ensures that the driver is the only device using the zigbee network to flash a device. This ensures that the delivery of the firmware update won’t be slowed down due to other firmware updates from other devices.

All reflash traffic is sent to the device using standard SendZigbeePacket and OnZigbeePacketIn commands/functions as described above.

GetBlobByName

Returns the un-encoded string containing the firmware update data of the specified BLOB (Binary Large Object). This API should not be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:(GetBlobByName)

Parameter Description
str Name of the Binary Large Object to retrieve from the .c4i file.

Returns

Binary data from the driver file.

Example

C4:("Blob1")

GetZigbeeEUID

Lua function called to retrieve a Zigbee device’s user ID. This API should not be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:GetZigbeeEUID()

Parameters

None

Returns

Value Description
str String representing the EUID value

KeepReflashLock

If a driver takes longer than a minute to upload the firmware data to the device, it should call C4:KeepReflashLock. This request will maintain the reflash lock while updating. If a driver does not call KeepReflashLock, the Reflash Lock will be revoked after approximately one minute. This API should not be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:KeepReflashLock()

OnReflashLockGranted

Function called by Director when a Zigbee device grants communication access. Ensures that the driver is the only one currently granted permission to update the device.

Available from 1.6.0.

Signature

OnReflashLockGranted()

OnReflashLockRevoked

Function called by Director when a driver loses permission to perform a device update.

Available from 1.6.0.

Signature

OnReflashLockRevoked()

OnZigbeeOnlineStatusChanged

This function gets called when the Online status of a Zigbee node changes.

Available from 1.6.0.

Signature

OnZigbeeOnlineStatusChanged (strStatus, strVersion, strSkew)

Parameter Description
str Status: OFFLINE, ONLINE, REBOOT, UNKNOWN
str Version
str Skew

Example

function OnZigbeeOnlineStatusChanged (strStatus, strVersion, strSkew)
  print("Zigbee Status Changed: " .. strStatus)
  gZigbeeStatus = strStatus
end

SendZigbeePacket

This function sends a raw Zigbee packet to a Zigbee Binding. This functionality supports both the current Control 4 (EmberNet) as well as ZigBee Pro 1.1 transports. This API should not be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:SendZigbeePacket (strPacket,nProfileID, nClusterID, nGroupID, nSourceEndpoint, ndestinationEndpoint)

Parameter Description
str ZigBee supported command packet containing user data.
num Profile ID associated with the data packet
num Source Cluster library ID included within the Profile
num Zigbee device group ID
num Endpoint designated as the source of the data packet delivery.
num Endpoint designated as the recipient of the data packet delivery.

Returns

None

Usage Note

The following parameters are ignored when using the Control 4 (Embernet) Zigbee stack:

Packet data is still sent in the strPacket parameter. If using ZigBee Pro, all data (including strPacket) must conform to ZigBee Pro format.

Example

g_SequenceNumber=g_sequenceNumber + 1
strPacket = "0" .. Chartype .. string.format(%04x",g_SequenceNumber) ..     c4.dm.lv 100"

OnZigbeePacketIn

Receives an unsolicited zigbee packet from the device or a response to a command that was sent.

Available from 1.6.0.

Signature

OnZigbeePacketIn(strPacket,nProfileID, nClusterID, nGroupID, nSourceEndpoint, ndestinationEndpoint)

Parameter Description
str ZigBee supported command packet containing user data.
num Profile ID associated with the data packet
num Source Cluster library ID included within the Profile
num Zigbee device group ID
num Endpoint designated as the source of the data packet delivery.
num Endpoint designated as the recipient of the data packet delivery.

Returns

None

Usage Note

The following parameters are ignored when using the Control 4 (Embernet) Zigbee stack:

Packet data is still sent in the strPacket parameter. If using ZigBee Pro, all data (including strPacket) must conform to ZigBee Pro format.

Example


function OnZigbeePacketIn (strPacket, idProfileID, idClusterID,
  idGroupID, sourceEndpoint,destinationEndpoint)
  print("OnZigbeePacketIn;" .. strPacket)
end

OnZigbeePacketFailed

Return function upon the unsuccessful delivery of a data packet.

Available from 1.6.0.

Signature

OnZigbeePacketFailed (strPacket, nProfileID, nClusterID, nGroupID, nSourceEndpoint, ndestinationEndpoint)

Parameter Description
str ZigBee supported command packet containing user data.
num Profile ID associated with the data packet
num Source Cluster library ID included within the Profile
num Zigbee device group ID
num Endpoint designated as the source of the data packet delivery.
num Endpoint designated as the recipient of the data packet delivery.

Returns

None

Usage Note

The following parameters are ignored when using the Control 4 (Embernet) Zigbee stack:

Packet data is still sent in the strPacket parameter. If using ZigBee Pro, all data (including strPacket) must conform to ZigBee Pro format.

Example

function OnZigbeePacketFailed (strPacket, idProfileID, idClusterID, idGroupID, sourceEndpoint,destinationEndpoint)
  print("OnZigbeePacketFailed;" .. strPacket)
end

OnZigbeePacketSuccess

Return function upon the successful delivery of a data packet.

Available from 1.6.0.

Signature

OnZigbeePacketSuccess(strPacket,nProfileID, nClusterID, nGroupID, nSourceEndpoint, ndestinationEndpoint)

Parameter Description
str ZigBee supported command packet containing user data.
num Profile ID associated with the data packet
num Source Cluster library ID included within the Profile
num Zigbee device group ID
num Endpoint designated as the source of the data packet delivery.
num Endpoint designated as the recipient of the data packet delivery.

Returns

None

Usage Note

The following parameters are ignored when using the Control 4 (Embernet) Zigbee stack:

Packet data is still sent in the strPacket parameter. If using ZigBee Pro, all data (including strPacket) must conform to ZigBee Pro format.

Example

function OnZigbeePacketSuccess (strPacket, idProfileID, idClusterID, idGroupID, sourceEndpoint,destinationEndpoint)
  print("OnZigbeePacketSuccess;"..strPacket)  
end

ReleaseReflashLock

Function to terminate the request for firmware data upon completion of update. This API should not be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:ReleaseReflashLock()

RequestReflashLock

Function that requests permission of Director to update the device. The driver receives permission when it receives the OnReflashLockGranted call. This API should not be invoked during OnDriverInit.

Available from 1.6.0.

Signature

C4:RequestReflashLock()

lua