The Anvil SDK automatically instruments all standard Control4 event handlers. Every time Control4 calls one of these functions, you'll see it in Anvil with the exact arguments that were passed.
How It Works
When you load the SDK, it registers wrappers for each C4 event handler:
function OnPropertyChanged ( sProperty ) end
You don't need to modify your handler implementations at all.
Agent Discovery
Capture is only active when the Anvil Agent is present on the controller. The SDK checks for it once Control4 has established bindings (in OnDriverLateInit):
Agent found. Anything captured during startup is delivered, and live streaming begins.
No agent. Startup capture is discarded and the SDK goes inert. Handler calls pass straight through to your code with no capture, no queuing, and no network activity, which is what makes it safe to ship the same build everywhere .
Events that fire before discovery completes are buffered in memory, capped at 500 (oldest dropped first). If the agent is installed after your driver loads, the SDK detects it and starts capturing from that moment on.
What You See
For each event, Anvil shows:
The handler name:
The arguments Control4 passed , matched to your parameter names where Lua's introspection allows (positional otherwise):
The return values from your handler, including multiple returns.
Timing:
And if something broke, the full error:
ERROR: attempt to index nil value driver.lua:142: in function <OnPropertyChanged>
Error stack traces include the value of every local variable in every frame at the moment of the error, so you can see exactly what your code was working with when it failed. Long values are bounded: strings truncate at 512 characters, and tables are capped in depth and size.
Sensitive Data
The SDK doesn't scan for or redact sensitive-looking values, so what your handler receives is what appears in Anvil. The exception is GetPrivateKeyPassword: the SDK records that the handler fired, but replaces its arguments with [REDACTED] and withholds its return value.
Captured Handlers
The SDK instruments 157 handlers across all Control4 event categories. Here's the complete list:
Command & Action Handlers
Handler When It Fires ExecuteCommandCommand sent to your driver ExecuteActionAction triggered
Data & Communication Handlers
Handler When It Fires OnDataFromUIData received from UI OnDataToUIData being sent to UI GetPrivateKeyPasswordPrivate key password requested UIRequestUI request from navigator ReceivedAsyncAsync response received ReceivedFromProxyData from a proxy binding
Driver Lifecycle Handlers
Handler When It Fires OnDriverInitDriver is initializing OnDriverLateInitAfter bindings are established OnDriverUpdateDriver is being updated OnDriverDestroyedDriver is being unloaded OnDriverAddedNew driver added to project OnDriverDisabledDriver was disabled OnAlivePeriodic health check
Connection & Network Handlers
Handler When It Fires OnConnectionStatusChangedConnection state changed OnServerConnectionStatusChangedServer connection changed OnNetworkBindingChangedNetwork binding changed OnConnectionAuthorizedConnection authorized ReceivedFromNetworkNetwork data received ReceivedFromSerialSerial data received OnAuthorizedConnectionDisconnectedAuthorized connection lost OnNetworkBindingStatusChangedNetwork binding status changed
Device Handlers
Handler When It Fires OnDeviceEventDevice-specific event OnDeviceOnlineDevice came online OnDeviceOfflineDevice went offline OnDeviceDiscoveredDevice discovered OnDeviceIdentifiedDevice identified OnDeviceIdentifyingDevice identification in progress OnDevicePreIdentifyBefore device identification OnDeviceIPAddressChangedDevice IP changed OnDeviceFirmwareChangedDevice firmware updated OnDeviceDataChangedDevice data modified OnDeviceUserInitiatedRemoveUser initiated device removal OnDeviceAlreadyIdentifiedDevice was already identified OnDeviceCancelIdentifyDevice identification cancelled OnDeviceIdentifiedNoLicenseDevice identified but no license OnPhysicalDeviceAddedPhysical device added OnPhysicalDeviceRemovedPhysical device removed OnDiscoveredDeviceAddedDiscovered device added OnDiscoveredDeviceChangedDiscovered device changed OnDiscoveredDeviceRemovedDiscovered device removed OnSearchTypeFoundSearch type found
Event & Timer Handlers
Handler When It Fires OnEventFiredEvent fired OnTimerExpiredLegacy timer fired OnScheduledEventScheduled event triggered OnSystemEventSystem-wide event OnEventAddedEvent added OnEventRemovedEvent removed OnEventModifiedEvent modified OnWatchedVariableChangedWatched variable changed OnAllCatch-all handler
Property & Variable Handlers
Handler When It Fires OnPropertyChangedProperty value changed OnProjectPropertyChangedProject property changed OnVariableChangedVariable value changed OnVariableAddedVariable created OnVariableRemovedVariable deleted OnVariableRenamedVariable renamed OnUserVariableAddedUser variable added OnItemDataChangedItem data changed OnAccessModeChangedAccess mode changed OnTimeChangedSystem time changed OnLatitudeChangedLatitude changed OnLongitudeChangedLongitude changed
Binding Handlers
Handler When It Fires OnBindingChangedBinding connection changed OnBindingAddedNew binding created OnBindingRemovedBinding removed OnBindingEntryAddedBinding entry added OnBindingEntryRemovedBinding entry removed OnBindingEntryRenamedBinding entry renamed OnVariableBindingAddedVariable binding added OnVariableBindingRemovedVariable binding removed OnVariableBindingRenamedVariable binding renamed OnVariableAddedToBindingVariable added to binding OnVariableRemovedFromBindingVariable removed from binding OnNetworkBindingAddedNetwork binding added OnNetworkBindingRemovedNetwork binding removed
Network Binding Handlers
Handler When It Fires OnNetworkBindingRegisteredNetwork binding registered OnNetworkBindingUnregisteredNetwork binding unregistered OnNetworkBindingAddressChangedNetwork binding address changed OnCIDRRulesChangedCIDR rules changed OnDirectorIPAddressChangedDirector IP changed
Project Handlers
Handler When It Fires OnProjectLoadedProject loaded OnProjectLoadingProject loading OnProjectNewNew project created OnProjectChangedProject changed OnProjectLockedProject locked OnProjectEnterLockEntering project lock OnProjectLeaveLockLeaving project lock OnProjectClearProject cleared OnLocaleChangedLocale changed
Server Handlers
Handler When It Fires OnServerStatusChangedServer status changed OnServerDataInServer data received OnSDDPDeviceStatusSDDP device status update
Handler When It Fires OnMediaSessionAddedMedia session added OnMediaSessionRemovedMedia session removed OnMediaSessionChangedMedia session changed OnMediaSessionVolumeLevelChangedVolume level changed OnMediaSessionVolumeSliderStateChangedVolume slider state changed OnMediaSessionMuteStateChangedMute state changed OnMediaSessionDiscreteMuteChangedDiscrete mute changed OnMediaSessionDiscreteVolumeChangedDiscrete volume changed OnMediaSessionSliderTargetVolumeReachedSlider target volume reached
Handler When It Fires OnMediaDeviceAddedMedia device added OnMediaDeviceRemovedMedia device removed OnMediaDeviceChangedMedia device changed OnMediaInfoAddedMedia info added OnMediaInfoModifiedMedia info modified OnMediaRemovedFromDeviceMedia removed from device
Handler When It Fires OnSongAddedToPlaylistSong added to playlist OnSongRemovedFromPlaylistSong removed from playlist OnMediaDataRemovedMedia data removed OnMediaSessionMediaInfoChangedSession media info changed
Item Handlers
Handler When It Fires OnItemAddedItem added OnItemMovedItem moved OnItemNameChangedItem name changed OnItemRemovedItem removed
Code Item Handlers
Handler When It Fires OnCodeItemAddedCode item added OnCodeItemRemovedCode item removed OnCodeItemMovedCode item moved OnCodeItemEnabledCode item enabled OnCodeItemCommandUpdatedCode item command updated OnCodeItemAddedToExpressionCode item added to expression
Zigbee Handlers
Handler When It Fires OnZigbeeNodeOfflineZigbee node went offline OnZigbeeNodeOnlineZigbee node came online OnZigbeeNodesChangedZigbee nodes changed OnZigbeeMeshChangedZigbee mesh changed OnZigbeeDuplicateMeshDuplicate Zigbee mesh detected OnZigbeeNetworkHealthZigbee network health update OnZigbeeNodeUpdateStatusNode update status OnZigbeeNodeUpdateSucceededNode update succeeded OnZigbeeNodeUpdateFailedNode update failed OnZigbeeZserverChangedZserver changed OnZigbeeZapsChangedZaps changed OnZigBeeStickPresentZigbee stick present OnZigBeeStickRemovedZigbee stick removed
System Update & Discovery Handlers
Handler When It Fires OnSystemUpdateStartedSystem update started OnSystemUpdateFinishedSystem update finished OnSystemShutDownSystem shutting down OnSDDPDeviceDiscoverSDDP device discovered OnSysmanResponseSysman response received OnReflashLockGrantedReflash lock granted OnReflashLockRevokedReflash lock revoked OnControllerDisabledController disabled
Notification Handlers
Handler When It Fires GetNotificationAttachmentURLGet notification attachment URL GetNotificationAttachmentFileGet notification attachment file GetNotificationAttachmentBytesGet notification attachment bytes FinishedWithNotificationAttachmentNotification attachment finished
List Handlers
Handler When It Fires ListMIBReceivedMIB list received ListNewControlNew control list ListEventList event ListNewListNew list created
Other Handlers
Handler When It Fires OnZipcodeChangedZipcode changed OnPIPPIP event OnTimezoneChangedTimezone changed
What's NOT Captured
Due to Lua limitations with protected userdata, these require manual capture :
C4:SetTimer() callbacks
C4:url():OnDone() callbacks
Other async callbacks passed to C4 methods
The SDK can't wrap these automatically, but provides simple APIs to capture them.