Module pyControl4.director
Handles communication with a Control4 Director, and provides functions for getting details about items on the Director.
Expand source code
"""Handles communication with a Control4 Director, and provides functions for
getting details about items on the Director.
"""
import aiohttp
import async_timeout
import json
from .error_handling import checkResponseForError
class C4Director:
def __init__(
self,
ip,
director_bearer_token,
session_no_verify_ssl: aiohttp.ClientSession = None,
):
"""Creates a Control4 Director object.
Parameters:
`ip` - The IP address of the Control4 Director/Controller.
`director_bearer_token` - The bearer token used to authenticate
with the Director.
See `pyControl4.account.C4Account.getDirectorBearerToken`
for how to get this.
`session` - (Optional) Allows the use of an
`aiohttp.ClientSession` object
for all network requests. This
session will not be closed by the library.
If not provided, the library will open and
close its own `ClientSession`s as needed.
"""
self.base_url = "https://{}".format(ip)
self.headers = {"Authorization": "Bearer {}".format(director_bearer_token)}
self.director_bearer_token = director_bearer_token
self.session = session_no_verify_ssl
async def sendGetRequest(self, uri):
"""Sends a GET request to the specified API URI.
Returns the Director's JSON response as a string.
Parameters:
`uri` - The API URI to send the request to. Do not include the IP
address of the Director.
"""
if self.session is None:
async with aiohttp.ClientSession(
connector=aiohttp.TCPConnector(verify_ssl=False)
) as session:
with async_timeout.timeout(10):
async with session.get(
self.base_url + uri, headers=self.headers
) as resp:
await checkResponseForError(await resp.text())
return await resp.text()
else:
with async_timeout.timeout(10):
async with self.session.get(
self.base_url + uri, headers=self.headers
) as resp:
await checkResponseForError(await resp.text())
return await resp.text()
async def sendPostRequest(self, uri, command, params, async_variable=True):
"""Sends a POST request to the specified API URI. Used to send commands
to the Director.
Returns the Director's JSON response as a string.
Parameters:
`uri` - The API URI to send the request to. Do not include the IP
address of the Director.
`command` - The Control4 command to send.
`params` - The parameters of the command, provided as a dictionary.
"""
dataDictionary = {
"async": async_variable,
"command": command,
"tParams": params,
}
if self.session is None:
async with aiohttp.ClientSession(
connector=aiohttp.TCPConnector(verify_ssl=False)
) as session:
with async_timeout.timeout(10):
async with session.post(
self.base_url + uri, headers=self.headers, json=dataDictionary
) as resp:
await checkResponseForError(await resp.text())
return await resp.text()
else:
with async_timeout.timeout(10):
async with self.session.post(
self.base_url + uri, headers=self.headers, json=dataDictionary
) as resp:
await checkResponseForError(await resp.text())
return await resp.text()
async def getAllItemsByCategory(self, category):
"""Returns a JSON list of items related to a particular category.
Parameters:
`category` - Control4 Category Name: controllers, comfort, lights,
cameras, sensors, audio_video,
motorization, thermostats, motors,
control4_remote_hub,
outlet_wireless_dimmer, voice-scene
"""
return_list = await self.sendGetRequest(
"/api/v1/categories/{}".format(category)
)
return return_list
async def getAllItemInfo(self):
"""Returns a JSON list of all the items on the Director."""
return await self.sendGetRequest("/api/v1/items")
async def getItemInfo(self, item_id):
"""Returns a JSON list of the details of the specified item.
Parameters:
`item_id` - The Control4 item ID.
"""
return await self.sendGetRequest("/api/v1/items/{}".format(item_id))
async def getItemSetup(self, item_id):
"""Returns a JSON list of the setup info of the specified item.
Parameters:
`item_id` - The Control4 item ID.
"""
return await self.sendPostRequest(
"/api/v1/items/{}/commands".format(item_id), "GET_SETUP", "{}", False
)
async def getItemVariables(self, item_id):
"""Returns a JSON list of the variables available for the specified item.
Parameters:
`item_id` - The Control4 item ID.
"""
return await self.sendGetRequest("/api/v1/items/{}/variables".format(item_id))
async def getItemVariableValue(self, item_id, var_name):
"""Returns the value of the specified variable for the
specified item as a string.
Parameters:
`item_id` - The Control4 item ID.
`var_name` - The Control4 variable name or names.
"""
if isinstance(var_name, (tuple, list, set)):
var_name = ",".join(var_name)
data = await self.sendGetRequest(
"/api/v1/items/{}/variables?varnames={}".format(item_id, var_name)
)
if data == "[]":
raise ValueError(
"Empty response recieved from Director! The variable {} \
doesn't seem to exist for item {}.".format(
var_name, item_id
)
)
jsonDictionary = json.loads(data)
return jsonDictionary[0]["value"]
async def getAllItemVariableValue(self, var_name):
"""Returns a dictionary with the values of the specified variable
for all items that have it.
Parameters:
`var_name` - The Control4 variable name or names.
"""
if isinstance(var_name, (tuple, list, set)):
var_name = ",".join(var_name)
data = await self.sendGetRequest(
"/api/v1/items/variables?varnames={}".format(var_name)
)
if data == "[]":
raise ValueError(
"Empty response recieved from Director! The variable {} \
doesn't seem to exist for any items.".format(
var_name
)
)
jsonDictionary = json.loads(data)
return jsonDictionary
async def getItemCommands(self, item_id):
"""Returns a JSON list of the commands available for the specified item.
Parameters:
`item_id` - The Control4 item ID.
"""
return await self.sendGetRequest("/api/v1/items/{}/commands".format(item_id))
async def getItemNetwork(self, item_id):
"""Returns a JSON list of the network information for the specified item.
Parameters:
`item_id` - The Control4 item ID.
"""
return await self.sendGetRequest("/api/v1/items/{}/network".format(item_id))
async def getItemBindings(self, item_id):
"""Returns a JSON list of the bindings information for the specified item.
Parameters:
`item_id` - The Control4 item ID.
"""
return await self.sendGetRequest("/api/v1/items/{}/bindings".format(item_id))
async def getUiConfiguration(self):
"""Returns a dictionary of the JSON Control4 App UI Configuration enumerating rooms and capabilities
Returns:
{
"experiences": [
{
"type": "watch",
"sources": {
"source": [
{
"id": 59,
"type": "HDMI"
},
{
"id": 946,
"type": "HDMI"
},
{
"id": 950,
"type": "HDMI"
},
{
"id": 33,
"type": "VIDEO_SELECTION"
}
]
},
"active": false,
"room_id": 9,
"username": "primaryuser"
},
{
"type": "listen",
"sources": {
"source": [
{
"id": 298,
"type": "DIGITAL_AUDIO_SERVER",
"name": "My Music"
},
{
"id": 302,
"type": "AUDIO_SELECTION",
"name": "Stations"
},
{
"id": 306,
"type": "DIGITAL_AUDIO_SERVER",
"name": "ShairBridge"
},
{
"id": 937,
"type": "DIGITAL_AUDIO_SERVER",
"name": "Spotify Connect"
},
{
"id": 100002,
"type": "DIGITAL_AUDIO_CLIENT",
"name": "Digital Media"
}
]
},
"active": false,
"room_id": 9,
"username": "primaryuser"
},
{
"type": "cameras",
"sources": {
"source": [
{
"id": 877,
"type": "Camera"
},
...
}
...
}
"""
return await self.sendGetRequest("/api/v1/agents/ui_configuration")
Classes
class C4Director (ip, director_bearer_token, session_no_verify_ssl: aiohttp.client.ClientSession = None)
-
Creates a Control4 Director object.
Parameters
ip
- The IP address of the Control4 Director/Controller.director_bearer_token
- The bearer token used to authenticate with the Director. SeeC4Account.getDirectorBearerToken()
for how to get this.session
- (Optional) Allows the use of anaiohttp.ClientSession
object for all network requests. This session will not be closed by the library. If not provided, the library will open and close its ownClientSession
s as needed.Expand source code
class C4Director: def __init__( self, ip, director_bearer_token, session_no_verify_ssl: aiohttp.ClientSession = None, ): """Creates a Control4 Director object. Parameters: `ip` - The IP address of the Control4 Director/Controller. `director_bearer_token` - The bearer token used to authenticate with the Director. See `pyControl4.account.C4Account.getDirectorBearerToken` for how to get this. `session` - (Optional) Allows the use of an `aiohttp.ClientSession` object for all network requests. This session will not be closed by the library. If not provided, the library will open and close its own `ClientSession`s as needed. """ self.base_url = "https://{}".format(ip) self.headers = {"Authorization": "Bearer {}".format(director_bearer_token)} self.director_bearer_token = director_bearer_token self.session = session_no_verify_ssl async def sendGetRequest(self, uri): """Sends a GET request to the specified API URI. Returns the Director's JSON response as a string. Parameters: `uri` - The API URI to send the request to. Do not include the IP address of the Director. """ if self.session is None: async with aiohttp.ClientSession( connector=aiohttp.TCPConnector(verify_ssl=False) ) as session: with async_timeout.timeout(10): async with session.get( self.base_url + uri, headers=self.headers ) as resp: await checkResponseForError(await resp.text()) return await resp.text() else: with async_timeout.timeout(10): async with self.session.get( self.base_url + uri, headers=self.headers ) as resp: await checkResponseForError(await resp.text()) return await resp.text() async def sendPostRequest(self, uri, command, params, async_variable=True): """Sends a POST request to the specified API URI. Used to send commands to the Director. Returns the Director's JSON response as a string. Parameters: `uri` - The API URI to send the request to. Do not include the IP address of the Director. `command` - The Control4 command to send. `params` - The parameters of the command, provided as a dictionary. """ dataDictionary = { "async": async_variable, "command": command, "tParams": params, } if self.session is None: async with aiohttp.ClientSession( connector=aiohttp.TCPConnector(verify_ssl=False) ) as session: with async_timeout.timeout(10): async with session.post( self.base_url + uri, headers=self.headers, json=dataDictionary ) as resp: await checkResponseForError(await resp.text()) return await resp.text() else: with async_timeout.timeout(10): async with self.session.post( self.base_url + uri, headers=self.headers, json=dataDictionary ) as resp: await checkResponseForError(await resp.text()) return await resp.text() async def getAllItemsByCategory(self, category): """Returns a JSON list of items related to a particular category. Parameters: `category` - Control4 Category Name: controllers, comfort, lights, cameras, sensors, audio_video, motorization, thermostats, motors, control4_remote_hub, outlet_wireless_dimmer, voice-scene """ return_list = await self.sendGetRequest( "/api/v1/categories/{}".format(category) ) return return_list async def getAllItemInfo(self): """Returns a JSON list of all the items on the Director.""" return await self.sendGetRequest("/api/v1/items") async def getItemInfo(self, item_id): """Returns a JSON list of the details of the specified item. Parameters: `item_id` - The Control4 item ID. """ return await self.sendGetRequest("/api/v1/items/{}".format(item_id)) async def getItemSetup(self, item_id): """Returns a JSON list of the setup info of the specified item. Parameters: `item_id` - The Control4 item ID. """ return await self.sendPostRequest( "/api/v1/items/{}/commands".format(item_id), "GET_SETUP", "{}", False ) async def getItemVariables(self, item_id): """Returns a JSON list of the variables available for the specified item. Parameters: `item_id` - The Control4 item ID. """ return await self.sendGetRequest("/api/v1/items/{}/variables".format(item_id)) async def getItemVariableValue(self, item_id, var_name): """Returns the value of the specified variable for the specified item as a string. Parameters: `item_id` - The Control4 item ID. `var_name` - The Control4 variable name or names. """ if isinstance(var_name, (tuple, list, set)): var_name = ",".join(var_name) data = await self.sendGetRequest( "/api/v1/items/{}/variables?varnames={}".format(item_id, var_name) ) if data == "[]": raise ValueError( "Empty response recieved from Director! The variable {} \ doesn't seem to exist for item {}.".format( var_name, item_id ) ) jsonDictionary = json.loads(data) return jsonDictionary[0]["value"] async def getAllItemVariableValue(self, var_name): """Returns a dictionary with the values of the specified variable for all items that have it. Parameters: `var_name` - The Control4 variable name or names. """ if isinstance(var_name, (tuple, list, set)): var_name = ",".join(var_name) data = await self.sendGetRequest( "/api/v1/items/variables?varnames={}".format(var_name) ) if data == "[]": raise ValueError( "Empty response recieved from Director! The variable {} \ doesn't seem to exist for any items.".format( var_name ) ) jsonDictionary = json.loads(data) return jsonDictionary async def getItemCommands(self, item_id): """Returns a JSON list of the commands available for the specified item. Parameters: `item_id` - The Control4 item ID. """ return await self.sendGetRequest("/api/v1/items/{}/commands".format(item_id)) async def getItemNetwork(self, item_id): """Returns a JSON list of the network information for the specified item. Parameters: `item_id` - The Control4 item ID. """ return await self.sendGetRequest("/api/v1/items/{}/network".format(item_id)) async def getItemBindings(self, item_id): """Returns a JSON list of the bindings information for the specified item. Parameters: `item_id` - The Control4 item ID. """ return await self.sendGetRequest("/api/v1/items/{}/bindings".format(item_id)) async def getUiConfiguration(self): """Returns a dictionary of the JSON Control4 App UI Configuration enumerating rooms and capabilities Returns: { "experiences": [ { "type": "watch", "sources": { "source": [ { "id": 59, "type": "HDMI" }, { "id": 946, "type": "HDMI" }, { "id": 950, "type": "HDMI" }, { "id": 33, "type": "VIDEO_SELECTION" } ] }, "active": false, "room_id": 9, "username": "primaryuser" }, { "type": "listen", "sources": { "source": [ { "id": 298, "type": "DIGITAL_AUDIO_SERVER", "name": "My Music" }, { "id": 302, "type": "AUDIO_SELECTION", "name": "Stations" }, { "id": 306, "type": "DIGITAL_AUDIO_SERVER", "name": "ShairBridge" }, { "id": 937, "type": "DIGITAL_AUDIO_SERVER", "name": "Spotify Connect" }, { "id": 100002, "type": "DIGITAL_AUDIO_CLIENT", "name": "Digital Media" } ] }, "active": false, "room_id": 9, "username": "primaryuser" }, { "type": "cameras", "sources": { "source": [ { "id": 877, "type": "Camera" }, ... } ... } """ return await self.sendGetRequest("/api/v1/agents/ui_configuration")
Methods
async def getAllItemInfo(self)
-
Returns a JSON list of all the items on the Director.
Expand source code
async def getAllItemInfo(self): """Returns a JSON list of all the items on the Director.""" return await self.sendGetRequest("/api/v1/items")
async def getAllItemVariableValue(self, var_name)
-
Returns a dictionary with the values of the specified variable for all items that have it.
Parameters
var_name
- The Control4 variable name or names.Expand source code
async def getAllItemVariableValue(self, var_name): """Returns a dictionary with the values of the specified variable for all items that have it. Parameters: `var_name` - The Control4 variable name or names. """ if isinstance(var_name, (tuple, list, set)): var_name = ",".join(var_name) data = await self.sendGetRequest( "/api/v1/items/variables?varnames={}".format(var_name) ) if data == "[]": raise ValueError( "Empty response recieved from Director! The variable {} \ doesn't seem to exist for any items.".format( var_name ) ) jsonDictionary = json.loads(data) return jsonDictionary
async def getAllItemsByCategory(self, category)
-
Returns a JSON list of items related to a particular category.
Parameters
category
- Control4 Category Name: controllers, comfort, lights, cameras, sensors, audio_video, motorization, thermostats, motors, control4_remote_hub, outlet_wireless_dimmer, voice-sceneExpand source code
async def getAllItemsByCategory(self, category): """Returns a JSON list of items related to a particular category. Parameters: `category` - Control4 Category Name: controllers, comfort, lights, cameras, sensors, audio_video, motorization, thermostats, motors, control4_remote_hub, outlet_wireless_dimmer, voice-scene """ return_list = await self.sendGetRequest( "/api/v1/categories/{}".format(category) ) return return_list
async def getItemBindings(self, item_id)
-
Returns a JSON list of the bindings information for the specified item.
Parameters
item_id
- The Control4 item ID.Expand source code
async def getItemBindings(self, item_id): """Returns a JSON list of the bindings information for the specified item. Parameters: `item_id` - The Control4 item ID. """ return await self.sendGetRequest("/api/v1/items/{}/bindings".format(item_id))
async def getItemCommands(self, item_id)
-
Returns a JSON list of the commands available for the specified item.
Parameters
item_id
- The Control4 item ID.Expand source code
async def getItemCommands(self, item_id): """Returns a JSON list of the commands available for the specified item. Parameters: `item_id` - The Control4 item ID. """ return await self.sendGetRequest("/api/v1/items/{}/commands".format(item_id))
async def getItemInfo(self, item_id)
-
Returns a JSON list of the details of the specified item.
Parameters
item_id
- The Control4 item ID.Expand source code
async def getItemInfo(self, item_id): """Returns a JSON list of the details of the specified item. Parameters: `item_id` - The Control4 item ID. """ return await self.sendGetRequest("/api/v1/items/{}".format(item_id))
async def getItemNetwork(self, item_id)
-
Returns a JSON list of the network information for the specified item.
Parameters
item_id
- The Control4 item ID.Expand source code
async def getItemNetwork(self, item_id): """Returns a JSON list of the network information for the specified item. Parameters: `item_id` - The Control4 item ID. """ return await self.sendGetRequest("/api/v1/items/{}/network".format(item_id))
async def getItemSetup(self, item_id)
-
Returns a JSON list of the setup info of the specified item.
Parameters
item_id
- The Control4 item ID.Expand source code
async def getItemSetup(self, item_id): """Returns a JSON list of the setup info of the specified item. Parameters: `item_id` - The Control4 item ID. """ return await self.sendPostRequest( "/api/v1/items/{}/commands".format(item_id), "GET_SETUP", "{}", False )
async def getItemVariableValue(self, item_id, var_name)
-
Returns the value of the specified variable for the specified item as a string.
Parameters
item_id
- The Control4 item ID.var_name
- The Control4 variable name or names.Expand source code
async def getItemVariableValue(self, item_id, var_name): """Returns the value of the specified variable for the specified item as a string. Parameters: `item_id` - The Control4 item ID. `var_name` - The Control4 variable name or names. """ if isinstance(var_name, (tuple, list, set)): var_name = ",".join(var_name) data = await self.sendGetRequest( "/api/v1/items/{}/variables?varnames={}".format(item_id, var_name) ) if data == "[]": raise ValueError( "Empty response recieved from Director! The variable {} \ doesn't seem to exist for item {}.".format( var_name, item_id ) ) jsonDictionary = json.loads(data) return jsonDictionary[0]["value"]
async def getItemVariables(self, item_id)
-
Returns a JSON list of the variables available for the specified item.
Parameters
item_id
- The Control4 item ID.Expand source code
async def getItemVariables(self, item_id): """Returns a JSON list of the variables available for the specified item. Parameters: `item_id` - The Control4 item ID. """ return await self.sendGetRequest("/api/v1/items/{}/variables".format(item_id))
async def getUiConfiguration(self)
-
Returns a dictionary of the JSON Control4 App UI Configuration enumerating rooms and capabilities
Returns
{ "experiences": [ { "type": "watch", "sources": { "source": [ { "id": 59, "type": "HDMI" }, { "id": 946, "type": "HDMI" }, { "id": 950, "type": "HDMI" }, { "id": 33, "type": "VIDEO_SELECTION" } ] }, "active": false, "room_id": 9, "username": "primaryuser" }, { "type": "listen", "sources": { "source": [ { "id": 298, "type": "DIGITAL_AUDIO_SERVER", "name": "My Music" }, { "id": 302, "type": "AUDIO_SELECTION", "name": "Stations" }, { "id": 306, "type": "DIGITAL_AUDIO_SERVER", "name": "ShairBridge" }, { "id": 937, "type": "DIGITAL_AUDIO_SERVER", "name": "Spotify Connect" }, { "id": 100002, "type": "DIGITAL_AUDIO_CLIENT", "name": "Digital Media" } ] }, "active": false, "room_id": 9, "username": "primaryuser" }, { "type": "cameras", "sources": { "source": [ { "id": 877, "type": "Camera" }, … } … }
Expand source code
async def getUiConfiguration(self): """Returns a dictionary of the JSON Control4 App UI Configuration enumerating rooms and capabilities Returns: { "experiences": [ { "type": "watch", "sources": { "source": [ { "id": 59, "type": "HDMI" }, { "id": 946, "type": "HDMI" }, { "id": 950, "type": "HDMI" }, { "id": 33, "type": "VIDEO_SELECTION" } ] }, "active": false, "room_id": 9, "username": "primaryuser" }, { "type": "listen", "sources": { "source": [ { "id": 298, "type": "DIGITAL_AUDIO_SERVER", "name": "My Music" }, { "id": 302, "type": "AUDIO_SELECTION", "name": "Stations" }, { "id": 306, "type": "DIGITAL_AUDIO_SERVER", "name": "ShairBridge" }, { "id": 937, "type": "DIGITAL_AUDIO_SERVER", "name": "Spotify Connect" }, { "id": 100002, "type": "DIGITAL_AUDIO_CLIENT", "name": "Digital Media" } ] }, "active": false, "room_id": 9, "username": "primaryuser" }, { "type": "cameras", "sources": { "source": [ { "id": 877, "type": "Camera" }, ... } ... } """ return await self.sendGetRequest("/api/v1/agents/ui_configuration")
async def sendGetRequest(self, uri)
-
Sends a GET request to the specified API URI. Returns the Director's JSON response as a string.
Parameters
uri
- The API URI to send the request to. Do not include the IP address of the Director.Expand source code
async def sendGetRequest(self, uri): """Sends a GET request to the specified API URI. Returns the Director's JSON response as a string. Parameters: `uri` - The API URI to send the request to. Do not include the IP address of the Director. """ if self.session is None: async with aiohttp.ClientSession( connector=aiohttp.TCPConnector(verify_ssl=False) ) as session: with async_timeout.timeout(10): async with session.get( self.base_url + uri, headers=self.headers ) as resp: await checkResponseForError(await resp.text()) return await resp.text() else: with async_timeout.timeout(10): async with self.session.get( self.base_url + uri, headers=self.headers ) as resp: await checkResponseForError(await resp.text()) return await resp.text()
async def sendPostRequest(self, uri, command, params, async_variable=True)
-
Sends a POST request to the specified API URI. Used to send commands to the Director. Returns the Director's JSON response as a string.
Parameters
uri
- The API URI to send the request to. Do not include the IP address of the Director.command
- The Control4 command to send.params
- The parameters of the command, provided as a dictionary.Expand source code
async def sendPostRequest(self, uri, command, params, async_variable=True): """Sends a POST request to the specified API URI. Used to send commands to the Director. Returns the Director's JSON response as a string. Parameters: `uri` - The API URI to send the request to. Do not include the IP address of the Director. `command` - The Control4 command to send. `params` - The parameters of the command, provided as a dictionary. """ dataDictionary = { "async": async_variable, "command": command, "tParams": params, } if self.session is None: async with aiohttp.ClientSession( connector=aiohttp.TCPConnector(verify_ssl=False) ) as session: with async_timeout.timeout(10): async with session.post( self.base_url + uri, headers=self.headers, json=dataDictionary ) as resp: await checkResponseForError(await resp.text()) return await resp.text() else: with async_timeout.timeout(10): async with self.session.post( self.base_url + uri, headers=self.headers, json=dataDictionary ) as resp: await checkResponseForError(await resp.text()) return await resp.text()