Module pyControl4.alarm
Controls Control4 security panel and contact sensor (door, window, motion) devices.
Classes
class C4ContactSensor (director: C4Director, item_id: int)-
Expand source code
class C4ContactSensor: def __init__(self, director: C4Director, item_id: int) -> None: """Creates a Control4 Contact Sensor object. Parameters: `director` - A `pyControl4.director.C4Director` object that corresponds to the Control4 Director that the contact sensor is connected to. `item_id` - The Control4 item ID of the contact sensor. """ self.director = director self.item_id = item_id async def get_contact_state(self) -> bool | None: """Returns `True` if contact is triggered (door/window is closed, motion is detected), otherwise returns `False`. """ contact_state = await self.director.get_item_variable_value( self.item_id, "ContactState" ) if contact_state is None: return None return bool(contact_state)Creates a Control4 Contact Sensor object.
Parameters
director- AC4Directorobject that corresponds to the Control4 Director that the contact sensor is connected to.item_id- The Control4 item ID of the contact sensor.Methods
async def get_contact_state(self) ‑> bool | None-
Expand source code
async def get_contact_state(self) -> bool | None: """Returns `True` if contact is triggered (door/window is closed, motion is detected), otherwise returns `False`. """ contact_state = await self.director.get_item_variable_value( self.item_id, "ContactState" ) if contact_state is None: return None return bool(contact_state)Returns
Trueif contact is triggered (door/window is closed, motion is detected), otherwise returnsFalse.
class C4SecurityPanel (director: C4Director, item_id: int)-
Expand source code
class C4SecurityPanel(C4Entity): async def get_arm_state(self) -> str | None: """ NOTE: Prefer using `get_partition_state()` and `get_armed_type()` over this method. Returns the arm state of the security panel as "DISARMED", "ARMED_HOME", or "ARMED_AWAY". """ disarmed = await self.director.get_item_variable_value( self.item_id, "DISARMED_STATE" ) armed_home = await self.director.get_item_variable_value( self.item_id, "HOME_STATE" ) armed_away = await self.director.get_item_variable_value( self.item_id, "AWAY_STATE" ) try: if disarmed is not None and int(disarmed) == 1: return "DISARMED" elif armed_home is not None and int(armed_home) == 1: return "ARMED_HOME" elif armed_away is not None and int(armed_away) == 1: return "ARMED_AWAY" except (ValueError, TypeError): pass return None async def get_alarm_state(self) -> bool | None: """Returns `True` if alarm is triggered, otherwise returns `False`.""" alarm_state = await self.director.get_item_variable_value( self.item_id, "ALARM_STATE" ) if alarm_state is None: return None return bool(alarm_state) async def get_display_text(self) -> str | None: """Returns the display text of the security panel.""" display_text = await self.director.get_item_variable_value( self.item_id, "DISPLAY_TEXT" ) return display_text async def get_trouble_text(self) -> str | None: """Returns the trouble display text of the security panel.""" trouble_text = await self.director.get_item_variable_value( self.item_id, "TROUBLE_TEXT" ) return trouble_text async def get_partition_state(self) -> str | None: """Returns the partition state of the security panel. Possible values include "DISARMED_NOT_READY", "DISARMED_READY", "ARMED_HOME", "ARMED_AWAY", "EXIT_DELAY", "ENTRY_DELAY" """ partition_state = await self.director.get_item_variable_value( self.item_id, "PARTITION_STATE" ) return partition_state async def get_delay_time_total(self) -> int | None: """Returns the total exit delay time. Returns 0 if an exit delay is not currently running. """ delay_time_total = await self.director.get_item_variable_value( self.item_id, "DELAY_TIME_TOTAL" ) return int(delay_time_total) if delay_time_total is not None else None async def get_delay_time_remaining(self) -> int | None: """Returns the remaining exit delay time. Returns 0 if an exit delay is not currently running. """ delay_time_remaining = await self.director.get_item_variable_value( self.item_id, "DELAY_TIME_REMAINING" ) return int(delay_time_remaining) if delay_time_remaining is not None else None async def get_open_zone_count(self) -> int | None: """Returns the number of open/unsecured zones.""" open_zone_count = await self.director.get_item_variable_value( self.item_id, "OPEN_ZONE_COUNT" ) return int(open_zone_count) if open_zone_count is not None else None async def get_alarm_type(self) -> str | None: """Returns details about the current alarm type.""" alarm_type = await self.director.get_item_variable_value( self.item_id, "ALARM_TYPE" ) return alarm_type async def get_armed_type(self) -> str | None: """Returns details about the current arm type.""" armed_type = await self.director.get_item_variable_value( self.item_id, "ARMED_TYPE" ) return armed_type async def get_last_emergency(self) -> str | None: """Returns details about the last emergency trigger.""" last_emergency = await self.director.get_item_variable_value( self.item_id, "LAST_EMERGENCY" ) return last_emergency async def get_last_arm_failure(self) -> str | None: """Returns details about the last arm failure.""" last_arm_failed = await self.director.get_item_variable_value( self.item_id, "LAST_ARM_FAILED" ) return last_arm_failed async def set_arm(self, usercode: str, mode: str) -> None: """Arms the security panel with the specified mode. Parameters: `usercode` - PIN/code for arming the system. `mode` - Arm mode to use. This depends on what is supported by the security panel itself. """ usercode = str(usercode) await self.director.send_post_request( f"/api/v1/items/{self.item_id}/commands", "PARTITION_ARM", {"ArmType": mode, "UserCode": usercode}, ) async def set_disarm(self, usercode: str) -> None: """Disarms the security panel. Parameters: `usercode` - PIN/code for disarming the system. """ usercode = str(usercode) await self.director.send_post_request( f"/api/v1/items/{self.item_id}/commands", "PARTITION_DISARM", {"UserCode": usercode}, ) async def get_emergency_types(self) -> list[str]: """Returns the available emergency types as a list. Possible types are "Fire", "Medical", "Panic", and "Police". """ types_list: list[str] = [] data = await self.director.get_item_info(self.item_id) if not data or not isinstance(data, list) or len(data) == 0: return types_list capabilities = data[0].get("capabilities", {}) if capabilities.get("has_fire"): types_list.append("Fire") if capabilities.get("has_medical"): types_list.append("Medical") if capabilities.get("has_panic"): types_list.append("Panic") if capabilities.get("has_police"): types_list.append("Police") return types_list async def get_arm_types(self) -> list[str]: """Returns the available arm types as a list.""" data = await self.director.get_item_info(self.item_id) if not data or not isinstance(data, list) or len(data) == 0: return [] capabilities = data[0].get("capabilities", {}) arm_types_str = capabilities.get("arm_types", "") if not arm_types_str: return [] return [t.strip() for t in arm_types_str.split(",") if t.strip()] async def trigger_emergency(self, emergency_type: str) -> None: """Triggers an emergency of the specified type. Parameters: `emergency_type` - Type of emergency: "Fire", "Medical", "Panic", or "Police" """ await self.director.send_post_request( f"/api/v1/items/{self.item_id}/commands", "EXECUTE_EMERGENCY", {"EmergencyType": emergency_type}, ) async def send_key_press(self, key: str) -> None: """Sends a single keypress to the security panel's virtual keypad (if supported). Parameters: `key` - Keypress to send. Only one key at a time. """ key = str(key) await self.director.send_post_request( f"/api/v1/items/{self.item_id}/commands", "KEY_PRESS", {"KeyName": key}, )Creates a Control4 object.
Parameters
director- AC4Directorobject that corresponds to the Control4 Director that the device is connected to.item_id- The Control4 item ID.Ancestors
Methods
async def get_alarm_state(self) ‑> bool | None-
Expand source code
async def get_alarm_state(self) -> bool | None: """Returns `True` if alarm is triggered, otherwise returns `False`.""" alarm_state = await self.director.get_item_variable_value( self.item_id, "ALARM_STATE" ) if alarm_state is None: return None return bool(alarm_state)Returns
Trueif alarm is triggered, otherwise returnsFalse. async def get_alarm_type(self) ‑> str | None-
Expand source code
async def get_alarm_type(self) -> str | None: """Returns details about the current alarm type.""" alarm_type = await self.director.get_item_variable_value( self.item_id, "ALARM_TYPE" ) return alarm_typeReturns details about the current alarm type.
async def get_arm_state(self) ‑> str | None-
Expand source code
async def get_arm_state(self) -> str | None: """ NOTE: Prefer using `get_partition_state()` and `get_armed_type()` over this method. Returns the arm state of the security panel as "DISARMED", "ARMED_HOME", or "ARMED_AWAY". """ disarmed = await self.director.get_item_variable_value( self.item_id, "DISARMED_STATE" ) armed_home = await self.director.get_item_variable_value( self.item_id, "HOME_STATE" ) armed_away = await self.director.get_item_variable_value( self.item_id, "AWAY_STATE" ) try: if disarmed is not None and int(disarmed) == 1: return "DISARMED" elif armed_home is not None and int(armed_home) == 1: return "ARMED_HOME" elif armed_away is not None and int(armed_away) == 1: return "ARMED_AWAY" except (ValueError, TypeError): pass return NoneNOTE: Prefer using
get_partition_state()andget_armed_type()over this method. Returns the arm state of the security panel as "DISARMED", "ARMED_HOME", or "ARMED_AWAY". async def get_arm_types(self) ‑> list[str]-
Expand source code
async def get_arm_types(self) -> list[str]: """Returns the available arm types as a list.""" data = await self.director.get_item_info(self.item_id) if not data or not isinstance(data, list) or len(data) == 0: return [] capabilities = data[0].get("capabilities", {}) arm_types_str = capabilities.get("arm_types", "") if not arm_types_str: return [] return [t.strip() for t in arm_types_str.split(",") if t.strip()]Returns the available arm types as a list.
async def get_armed_type(self) ‑> str | None-
Expand source code
async def get_armed_type(self) -> str | None: """Returns details about the current arm type.""" armed_type = await self.director.get_item_variable_value( self.item_id, "ARMED_TYPE" ) return armed_typeReturns details about the current arm type.
async def get_delay_time_remaining(self) ‑> int | None-
Expand source code
async def get_delay_time_remaining(self) -> int | None: """Returns the remaining exit delay time. Returns 0 if an exit delay is not currently running. """ delay_time_remaining = await self.director.get_item_variable_value( self.item_id, "DELAY_TIME_REMAINING" ) return int(delay_time_remaining) if delay_time_remaining is not None else NoneReturns the remaining exit delay time. Returns 0 if an exit delay is not currently running.
async def get_delay_time_total(self) ‑> int | None-
Expand source code
async def get_delay_time_total(self) -> int | None: """Returns the total exit delay time. Returns 0 if an exit delay is not currently running. """ delay_time_total = await self.director.get_item_variable_value( self.item_id, "DELAY_TIME_TOTAL" ) return int(delay_time_total) if delay_time_total is not None else NoneReturns the total exit delay time. Returns 0 if an exit delay is not currently running.
async def get_display_text(self) ‑> str | None-
Expand source code
async def get_display_text(self) -> str | None: """Returns the display text of the security panel.""" display_text = await self.director.get_item_variable_value( self.item_id, "DISPLAY_TEXT" ) return display_textReturns the display text of the security panel.
async def get_emergency_types(self) ‑> list[str]-
Expand source code
async def get_emergency_types(self) -> list[str]: """Returns the available emergency types as a list. Possible types are "Fire", "Medical", "Panic", and "Police". """ types_list: list[str] = [] data = await self.director.get_item_info(self.item_id) if not data or not isinstance(data, list) or len(data) == 0: return types_list capabilities = data[0].get("capabilities", {}) if capabilities.get("has_fire"): types_list.append("Fire") if capabilities.get("has_medical"): types_list.append("Medical") if capabilities.get("has_panic"): types_list.append("Panic") if capabilities.get("has_police"): types_list.append("Police") return types_listReturns the available emergency types as a list.
Possible types are "Fire", "Medical", "Panic", and "Police".
async def get_last_arm_failure(self) ‑> str | None-
Expand source code
async def get_last_arm_failure(self) -> str | None: """Returns details about the last arm failure.""" last_arm_failed = await self.director.get_item_variable_value( self.item_id, "LAST_ARM_FAILED" ) return last_arm_failedReturns details about the last arm failure.
async def get_last_emergency(self) ‑> str | None-
Expand source code
async def get_last_emergency(self) -> str | None: """Returns details about the last emergency trigger.""" last_emergency = await self.director.get_item_variable_value( self.item_id, "LAST_EMERGENCY" ) return last_emergencyReturns details about the last emergency trigger.
async def get_open_zone_count(self) ‑> int | None-
Expand source code
async def get_open_zone_count(self) -> int | None: """Returns the number of open/unsecured zones.""" open_zone_count = await self.director.get_item_variable_value( self.item_id, "OPEN_ZONE_COUNT" ) return int(open_zone_count) if open_zone_count is not None else NoneReturns the number of open/unsecured zones.
async def get_partition_state(self) ‑> str | None-
Expand source code
async def get_partition_state(self) -> str | None: """Returns the partition state of the security panel. Possible values include "DISARMED_NOT_READY", "DISARMED_READY", "ARMED_HOME", "ARMED_AWAY", "EXIT_DELAY", "ENTRY_DELAY" """ partition_state = await self.director.get_item_variable_value( self.item_id, "PARTITION_STATE" ) return partition_stateReturns the partition state of the security panel.
Possible values include "DISARMED_NOT_READY", "DISARMED_READY", "ARMED_HOME", "ARMED_AWAY", "EXIT_DELAY", "ENTRY_DELAY"
async def get_trouble_text(self) ‑> str | None-
Expand source code
async def get_trouble_text(self) -> str | None: """Returns the trouble display text of the security panel.""" trouble_text = await self.director.get_item_variable_value( self.item_id, "TROUBLE_TEXT" ) return trouble_textReturns the trouble display text of the security panel.
async def send_key_press(self, key: str) ‑> None-
Expand source code
async def send_key_press(self, key: str) -> None: """Sends a single keypress to the security panel's virtual keypad (if supported). Parameters: `key` - Keypress to send. Only one key at a time. """ key = str(key) await self.director.send_post_request( f"/api/v1/items/{self.item_id}/commands", "KEY_PRESS", {"KeyName": key}, )Sends a single keypress to the security panel's virtual keypad (if supported).
Parameters
key- Keypress to send. Only one key at a time. async def set_arm(self, usercode: str, mode: str) ‑> None-
Expand source code
async def set_arm(self, usercode: str, mode: str) -> None: """Arms the security panel with the specified mode. Parameters: `usercode` - PIN/code for arming the system. `mode` - Arm mode to use. This depends on what is supported by the security panel itself. """ usercode = str(usercode) await self.director.send_post_request( f"/api/v1/items/{self.item_id}/commands", "PARTITION_ARM", {"ArmType": mode, "UserCode": usercode}, )Arms the security panel with the specified mode.
Parameters
usercode- PIN/code for arming the system.mode- Arm mode to use. This depends on what is supported by the security panel itself. async def set_disarm(self, usercode: str) ‑> None-
Expand source code
async def set_disarm(self, usercode: str) -> None: """Disarms the security panel. Parameters: `usercode` - PIN/code for disarming the system. """ usercode = str(usercode) await self.director.send_post_request( f"/api/v1/items/{self.item_id}/commands", "PARTITION_DISARM", {"UserCode": usercode}, )Disarms the security panel.
Parameters
usercode- PIN/code for disarming the system. async def trigger_emergency(self, emergency_type: str) ‑> None-
Expand source code
async def trigger_emergency(self, emergency_type: str) -> None: """Triggers an emergency of the specified type. Parameters: `emergency_type` - Type of emergency: "Fire", "Medical", "Panic", or "Police" """ await self.director.send_post_request( f"/api/v1/items/{self.item_id}/commands", "EXECUTE_EMERGENCY", {"EmergencyType": emergency_type}, )Triggers an emergency of the specified type.
Parameters
emergency_type- Type of emergency: "Fire", "Medical", "Panic", or "Police"