Skip to content

Commit

Permalink
Merge pull request #12 from roopesh/configurable-topics
Browse files Browse the repository at this point in the history
Made topics configurable and fixed timeout handler
  • Loading branch information
roopesh authored Apr 27, 2021
2 parents 93098ce + 69ce4e4 commit 12a92ce
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 48 deletions.
44 changes: 36 additions & 8 deletions apps/ad-qolsys/door_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,26 @@

class door_window:
def __init__(self, zoneid: int, name: str, state: str, partition_id: int, device_class="door", **kwargs):
""" Arguments:
"""
Arguments:
zoneid: int
name: str
state: str
partition_id: int
device_class: str = door"""
device_class: str = door
will_topic
birth_topic
will_payload = offline
birth_payload = offline
"""
self.__c_will_topic__ = "will_topic"
self.__c_will_payload__ = "will_payload"
self.__c_birth_topic__ = "birth_topic"
self.__c_birth_payload__ = "birth_payload"
self.__c_homeassistant_mqtt_discovery_topic__ = "homeassistant_mqtt_discovery_topic"
self.__c_mqtt_state_topic__ = "mqtt_state_topic"
self.__c_mqtt_availability_topic__ = "mqtt_availability_topic"

self.zoneid = zoneid
self.friendly_name = name
self.entity_id = re.sub("\W", "_", self.friendly_name).lower()
Expand All @@ -20,16 +30,21 @@ def __init__(self, zoneid: int, name: str, state: str, partition_id: int, device
self.device_class = device_class
self.payload_on = "Open"
self.payload_off = "Closed"
self.config_topic = "homeassistant/binary_sensor/" + self.entity_id + "/config"
self.state_topic = "mqtt_states/binary_sensor/" + self.entity_id + "/state"
self.availability_topic = "mqtt_availability/binary_sensor/" + self.entity_id + "/availability"
self.payload_available = "online"
self.payload_not_available = "offline"
self.homeassistant_mqtt_discovery_topic = kwargs[self.__c_homeassistant_mqtt_discovery_topic__] if self.__c_homeassistant_mqtt_discovery_topic__ in kwargs else "homeassistant/"
self.mqtt_state_topic = kwargs[self.__c_mqtt_state_topic__] if self.__c_mqtt_state_topic__ in kwargs else "mqtt-states/"
self.mqtt_availability_topic = kwargs[self.__c_mqtt_availability_topic__] if self.__c_mqtt_availability_topic__ in kwargs else "mqtt-availability/"

self.will_topic = kwargs[self.__c_will_topic__] if self.__c_will_topic__ in kwargs else "mqtt-client/status"
self.birth_topic = kwargs[self.__c_birth_topic__] if self.__c_birth_topic__ in kwargs else "mqtt-client/status"
self.will_payload = kwargs[self.__c_will_payload__] if self.__c_will_payload__ in kwargs else "offline"
self.birth_payload = kwargs[self.__c_birth_payload__] if self.__c_birth_payload__ in kwargs else "online"

self.config_topic = self.homeassistant_mqtt_discovery_topic + ("/" if not self.homeassistant_mqtt_discovery_topic.endswith("/") else "") + "binary_sensor/" + self.entity_id + "/config"
self.state_topic = self.mqtt_state_topic + "binary_sensor/" + self.entity_id + "/state"
self.availability_topic = self.mqtt_availability_topic + "binary_sensor/" + self.entity_id + "/availability"

@property
def availability_list(self):
al = [
Expand Down Expand Up @@ -65,10 +80,23 @@ def __str__(self):

me = ("zoneid: %s, entity_id: %s, friendly_name: %s, state: %s, \
partition_id: %s, device_class: %s, payload_on: %s, payload_off: %s, \
config_topic: %s, state_topic: %s" % (self.zoneid, self.entity_id, \
config_topic: %s, state_topic: %s, availability: %s" % (self.zoneid, self.entity_id, \
self.friendly_name, self.state, self.partition_id, self.device_class, \
self.payload_on, self.payload_off, self.config_topic, self.state_topic))
self.payload_on, self.payload_off, self.config_topic, self.state_topic, self.availability_list))
return me

def __repr__(self):
return self.__str__()
me = {
"zoneid": self.zoneid,
"entity_id": self.entity_id,
"friendly_name": self.friendly_name,
"state": self.state,
"partition_id": self.partition_id,
"device_class": self.device_class,
"payload_on": self.payload_on,
"payload_off": self.payload_off,
"config_topic": self.config_topic,
"state_topic": self.state_topic,
"availability": self.availability_list
}
return me
50 changes: 29 additions & 21 deletions apps/ad-qolsys/partition.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,31 @@ def __init__(self, p_id: int, name: str, status: str, code: int, confirm_code_ar
self.__c_will_payload__ = "will_payload"
self.__c_birth_topic__ = "birth_topic"
self.__c_birth_payload__ = "birth_payload"
self.__c_homeassistant_mqtt_discovery_topic__ = "homeassistant_mqtt_discovery_topic"
self.__c_mqtt_state_topic__ = "mqtt_state_topic"
self.__c_mqtt_availability_topic__ = "mqtt_availability_topic"

self.alarm_panel_config_topic = "homeassistant/alarm_control_panel/qolsys/" + self.entity_id + "/config"
self.alarm_panel_state_topic = "mqtt_states/alarm_control_panel/qolsys/" + self.entity_id + "/state"
self.availability_topic = "mqtt_availability/alarm_control_panel/qolsys/" + self.entity_id + "/availability"
self.status = status
self.code = code
self.confirm_code_arm = confirm_code_arm
self.confirm_code_disarm = confirm_code_disarm
self.token = token
self.payload_available = "online"
self.payload_not_available = "offline"
self.command_template = '{"event":"{% if action == \"ARM_HOME\" or action == \"ARM_AWAY\" %}ARM","arm_type":"{% if action == \"ARM_HOME\" %}stay{% else %}away{% endif %}"{% else %}{{action}}", "usercode":"' + str(self.code) + '"{% endif %}, "token":"' + self.token + '", "partition_id":"' + str(self.p_id) + '"}'
self.command_topic = kwargs[self.__c_command_topic__] if self.__c_command_topic__ in kwargs else "qolsys/requests"
self.will_topic = kwargs[self.__c_will_topic__] if self.__c_will_topic__ in kwargs else "mqtt-client/status"
self.birth_topic = kwargs[self.__c_birth_topic__] if self.__c_birth_topic__ in kwargs else "mqtt-client/status"
self.will_payload = kwargs[self.__c_will_payload__] if self.__c_will_payload__ in kwargs else "offline"
self.birth_payload = kwargs[self.__c_birth_payload__] if self.__c_birth_payload__ in kwargs else "online"
self.homeassistant_mqtt_discovery_topic = kwargs[self.__c_homeassistant_mqtt_discovery_topic__] if self.__c_homeassistant_mqtt_discovery_topic__ in kwargs else "homeassistant/"
self.mqtt_state_topic = kwargs[self.__c_mqtt_state_topic__] if self.__c_mqtt_state_topic__ in kwargs else "mqtt-states/"
self.mqtt_availability_topic = kwargs[self.__c_mqtt_availability_topic__] if self.__c_mqtt_availability_topic__ in kwargs else "mqtt-availability/"

self.alarm_panel_config_topic = self.homeassistant_mqtt_discovery_topic + "alarm_control_panel/qolsys/" + self.entity_id + "/config"
self.alarm_panel_state_topic = self.mqtt_state_topic + "alarm_control_panel/qolsys/" + self.entity_id + "/state"
self.availability_topic = self.mqtt_availability_topic + "alarm_control_panel/qolsys/" + self.entity_id + "/availability"
self.command_template = '{"event":"{% if action == \"ARM_HOME\" or action == \"ARM_AWAY\" %}ARM","arm_type":"{% if action == \"ARM_HOME\" %}stay{% else %}away{% endif %}"{% else %}{{action}}", "usercode":"' + str(self.code) + '"{% endif %}, "token":"' + self.token + '", "partition_id":"' + str(self.p_id) + '"}'

@property
def availability_list(self):
al = [
Expand Down Expand Up @@ -75,15 +82,6 @@ def alarm_config_payload(self):
payload.update({"code": self.code})
return payload

# def config_payload(self):
# payload = {
# "name": self.name,
# "state_topic": self.state_topic,
# "payload_on": self.payload_on,
# "payload_off": self.payload_off
# }
# return payload

@property
def code(self):
return self.__code
Expand All @@ -110,19 +108,19 @@ def status(self, status:str):
__c_DISARM__ = "DISARM"
__c_ENTRY_DELAY__ = "ENTRY_DELAY"
__c_ARM_AWAY__ = "ARM_AWAY"
valid_values = {__c_ARM_STAY__, __c_ARM_AWAY__, __c_ARM_DELAY__, __c_DISARM__, __c_ENTRY_DELAY__}
__c_ARM_AWAY_EXIT_DELAY__ = "ARM-AWAY-EXIT-DELAY"
valid_values = {__c_ARM_STAY__, __c_ARM_AWAY__, __c_ARM_DELAY__, __c_DISARM__, __c_ENTRY_DELAY__, __c_ARM_AWAY_EXIT_DELAY__}

if not status in valid_values:
self.__status = "unavailable"
raise ValueError("Not a valid status: '" + status + "' not in " + str(valid_values))
elif status in {__c_ARM_STAY__}:
# self.__status = self.payload_on
elif status in {__c_ARM_STAY__}: # Maps values to armed_home status
self.__status = self.__c_armed_home__
elif status in {__c_ARM_DELAY__}:
elif status in {__c_ARM_DELAY__, __c_ARM_AWAY_EXIT_DELAY__}: # Maps values to arming status
self.__status = self.__c_arming__
elif status in {__c_ENTRY_DELAY__, __c_ARM_AWAY__}:
elif status in {__c_ENTRY_DELAY__, __c_ARM_AWAY__}: # Maps panel status values to armed_away
self.__status = self.__c_armed_away__
elif status in {__c_DISARM__}:
# self.__status = self.payload_off
elif status in {__c_DISARM__}: # Maps panel status values to disarmed
self.__status = self.__c_disarmed__
else:
raise ValueError("Not sure why it wouldn't set the status")
Expand All @@ -145,4 +143,14 @@ def __str__(self):
return me

def __repr__(self):
return self.__str__()
me = {
"id": self.p_id,
"name": self.name,
"status": self.status,
"entity_id": self.entity_id,
"alarm_panel_config_topic": self.alarm_panel_config_topic,
"alarm_panel_state_topic": self.alarm_panel_state_topic,
"code": self.code,
"zones": self.zones
}
return me
46 changes: 44 additions & 2 deletions apps/ad-qolsys/qolsys_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,34 @@
# qolsys_confirm_disarm_code: True/False (Optional) Require the code for disarming
# qolsys_confirm_arm_code: True/False (Optional) Require the code for arming
# qolsys_disarm_code: (Required - if you want to disarm the alarm)
#
# qolsys_arm_away_always_instant: True/False (Optional) Set to true if all Arm Away commands should be instant; defaults to False

class QolsysClient(mqtt.Mqtt):
def get_arg(self, name: str, arr: list, default=None):

if not name:
raise ValueError("Need a name of a value")
if not arr:
arr = self.args

ret_value = arr[name] if name in arr else default

return ret_value

def fix_topic_name(self, topic_name):
try:
if topic_name:
if topic_name.endswith("/"):
return topic_name
else:
return (topic_name + "/")
else:
self.log("Not a valid topic: %s", topic_name, level="ERROR")
raise("Not a valid topic" + str(topic_name))
except:
self.log("Unable to fix topic_name: %s, Error: %s", topic_name, sys.exc_info(), level="ERROR")
return ""

def initialize(self):

# An array of the zones
Expand All @@ -51,9 +76,17 @@ def initialize(self):
self.__c_qolsys_confirm_disarm_code__ = "qolsys_confirm_disarm_code"
self.__c_qolsys_confirm_arm_code__ = "qolsys_confirm_arm_code"
self.__c_qolsys_arm_away_always_instant__ = "qolsys_arm_away_always_instant"
self.__c_homeassistant_mqtt_discovery_topic__ = "homeassistant_mqtt_discovery_topic"
self.__c_mqtt_state_topic__ = "mqtt_state_topic"
self.__c_mqtt_availability_topic__ = "mqtt_availability_topic"
self.__c_mqtt_will_topic__ = "will_topic"
self.__c_mqtt_will_payload__ = "will_payload"
self.__c_mqtt_birth_topic__ = "birth_topic"
self.__c_mqtt_birth_payload__ = "birth_payload"

# populate some variables we'll need to use throughout our app
self.mqtt_namespace = self.args[self.__c_mqtt_namespace__] if self.__c_mqtt_namespace__ in self.args else ""
self.mqtt_namespace = self.get_arg(name=self.__c_mqtt_namespace__, arr=self.args, default="")
# self.mqtt_namespace = self.args[self.__c_mqtt_namespace__] if self.__c_mqtt_namespace__ in self.args else ""
self.qolsys_host = self.args[self.__c_qolsys_host__]
self.qolsys_port = self.args[self.__c_qolsys_port__] if self.__c_qolsys_port__ in self.args else 12345
self.request_topic = self.args[self.__c_qolsys_request_topic__] if self.__c_qolsys_request_topic__ in self.args else "qolsys/requests"
Expand All @@ -69,8 +102,17 @@ def initialize(self):
self.qolsys_confirm_disarm_code = self.args[self.__c_qolsys_confirm_disarm_code__] if self.__c_qolsys_confirm_disarm_code__ in self.args else False
self.qolsys_confirm_arm_code = self.args[self.__c_qolsys_confirm_arm_code__] if self.__c_qolsys_confirm_arm_code__ in self.args else False
self.qolsys_arm_away_always_instant = self.args[self.__c_qolsys_arm_away_always_instant__] if self.__c_qolsys_arm_away_always_instant__ in self.args else False
self.homeassistant_mqtt_discovery_topic = self.fix_topic_name(self.get_arg(self.__c_homeassistant_mqtt_discovery_topic__, self.args, "homeassistant/"))
self.mqtt_state_topic = self.fix_topic_name(self.get_arg(self.__c_mqtt_state_topic__, self.args, "mqtt-states/"))
self.mqtt_availability_topic = self.fix_topic_name(self.get_arg(self.__c_mqtt_availability_topic__, self.args, "mqtt-availability/"))
self.mqtt_plugin_config = self.get_plugin_config(namespace=self.mqtt_namespace)
self.mqtt_will_topic = self.get_arg(name=self.__c_mqtt_will_topic__, arr=self.mqtt_plugin_config)
self.mqtt_will_payload = self.get_arg(name=self.__c_mqtt_will_payload__, arr=self.mqtt_plugin_config)
self.mqtt_birth_topic = self.get_arg(name=self.__c_mqtt_birth_topic__, arr=self.mqtt_plugin_config)
self.mqtt_birth_payload = self.get_arg(name=self.__c_mqtt_birth_payload__, arr=self.mqtt_plugin_config)



self.log("qolsys_host: %s, qolsys_port: %s, qolsys_token: %s, qolsys_timeout: %s, request_topic: %s", self.qolsys_host, self.qolsys_port, self.qolsys_token, self.qolsys_timeout, self.request_topic, level="DEBUG")
self.log("Creating qolsys_socket", level="INFO")
self.qolsys = qolsys_socket.qolsys(self)
Expand Down
Loading

0 comments on commit 12a92ce

Please sign in to comment.