Skip to content

Commit

Permalink
asterisk plugin: fix network callback issues
Browse files Browse the repository at this point in the history
  • Loading branch information
bmxp committed Sep 22, 2023
1 parent 1e0aa2f commit 8f687e1
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 84 deletions.
172 changes: 89 additions & 83 deletions asterisk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

class Asterisk(SmartPlugin):

PLUGIN_VERSION = "1.4.0"
PLUGIN_VERSION = "1.4.1"

DB = 'ast_db'
DEV = 'ast_dev'
Expand Down Expand Up @@ -77,6 +77,92 @@ def __init__(self, sh):
self._trigger_logics = {}
self._log_in = lib.log.Log(self.get_sh(), 'env.asterisk.log.in', ['start', 'name', 'number', 'duration', 'direction'])

def run(self):
"""
Run method for the plugin
"""
self.logger.debug("Run method called")
if self._client.connect():
self.alive = True
else:
self.logger.error(f'Connection to {self.host}:{self.port} not possible, plugin not starting')

def stop(self):
"""
Stop method for the plugin
"""
self.logger.debug("Stop method called")
if self._client.connected():
self._client.close()
self.alive = False
self._reply_lock.acquire()
self._reply_lock.notify()
self._reply_lock.release()


def parse_item(self, item):
"""
Default plugin parse_item method. Is called when the plugin is initialized.
The plugin can, corresponding to its attribute keywords, decide what to do with
the item in future, like adding it to an internal array for future reference
:param item: The item to process.
:return: If the plugin needs to be informed of an items change you should return a call back function
like the function update_item down below. An example when this is needed is the knx plugin
where parse_item returns the update_item function when the attribute knx_send is found.
This means that when the items value is about to be updated, the call back function is called
with the item, caller, source and dest as arguments and in case of the knx plugin the value
can be sent to the knx with a knx write function within the knx plugin.
"""
if self.has_iattr(item.conf, Asterisk.DEV):
self._devices[self.get_iattr_value(item.conf, Asterisk.DEV)] = item
if self.has_iattr(item.conf, Asterisk.BOX):
self._mailboxes[self.get_iattr_value(item.conf, Asterisk.BOX)] = item
if self.has_iattr(item.conf, Asterisk.DB):
return self.update_item


def parse_logic(self, logic):
"""
Default plugin parse_logic method
"""
if Asterisk.USEREVENT in logic.conf:
event = logic.conf[Asterisk.USEREVENT]
if event not in self._trigger_logics:
self._trigger_logics[event] = [logic]
else:
self._trigger_logics[event].append(logic)


def update_item(self, item, caller=None, source=None, dest=None):
"""
Item has been updated
This method is called, if the value of an item has been updated by SmartHomeNG.
It should write the changed value out to the device (hardware/interface) that
is managed by this plugin.
:param item: item to be updated towards the plugin
:param caller: if given it represents the callers name
:param source: if given it represents the source
:param dest: if given it represents the dest
"""
if self.alive and caller != self.get_shortname():
self.logger.debug("Update item: {}, item has been changed outside this plugin".format(item.id()))
if self.has_iattr(item.conf, Asterisk.DB):
value = item()
if isinstance(value, bool):
value = int(item())
self.db_write(self.get_iattr_value(item.conf, Asterisk.DB), value)


def handle_connect(self, client):
self._command(self._init_cmd, reply=False)
for mb in self._mailboxes:
mbc = self.mailbox_count(mb)
if mbc is not None:
self._mailboxes[mb](mbc[1])


def _command(self, d, reply=True):
"""
This function sends a command to the Asterisk Server
Expand Down Expand Up @@ -150,7 +236,8 @@ def hangup(self, hang):
if device == hang:
self._command({'Action': 'Hangup', 'Channel': channel}, reply=False)

def found_terminator(self, data):
def found_terminator(self, client, data):
"""called upon data reception"""
data = data.decode()
event = {}
for line in data.splitlines():
Expand Down Expand Up @@ -246,84 +333,3 @@ def _get_device(self, channel):
channel, s, d = channel.rpartition('-')
a, b, channel = channel.partition('/')
return channel

def parse_item(self, item):
"""
Default plugin parse_item method. Is called when the plugin is initialized.
The plugin can, corresponding to its attribute keywords, decide what to do with
the item in future, like adding it to an internal array for future reference
:param item: The item to process.
:return: If the plugin needs to be informed of an items change you should return a call back function
like the function update_item down below. An example when this is needed is the knx plugin
where parse_item returns the update_item function when the attribute knx_send is found.
This means that when the items value is about to be updated, the call back function is called
with the item, caller, source and dest as arguments and in case of the knx plugin the value
can be sent to the knx with a knx write function within the knx plugin.
"""
if self.has_iattr(item.conf, Asterisk.DEV):
self._devices[self.get_iattr_value(item.conf, Asterisk.DEV)] = item
if self.has_iattr(item.conf, Asterisk.BOX):
self._mailboxes[self.get_iattr_value(item.conf, Asterisk.BOX)] = item
if self.has_iattr(item.conf, Asterisk.DB):
return self.update_item

def update_item(self, item, caller=None, source=None, dest=None):
"""
Item has been updated
This method is called, if the value of an item has been updated by SmartHomeNG.
It should write the changed value out to the device (hardware/interface) that
is managed by this plugin.
:param item: item to be updated towards the plugin
:param caller: if given it represents the callers name
:param source: if given it represents the source
:param dest: if given it represents the dest
"""
if self.alive and caller != self.get_shortname():
self.logger.debug("Update item: {}, item has been changed outside this plugin".format(item.id()))
if self.has_iattr(item.conf, Asterisk.DB):
value = item()
if isinstance(value, bool):
value = int(item())
self.db_write(self.get_iattr_value(item.conf, Asterisk.DB), value)

def parse_logic(self, logic):
"""
Default plugin parse_logic method
"""
if Asterisk.USEREVENT in logic.conf:
event = logic.conf[Asterisk.USEREVENT]
if event not in self._trigger_logics:
self._trigger_logics[event] = [logic]
else:
self._trigger_logics[event].append(logic)

def run(self):
"""
Run method for the plugin
"""
self.logger.debug("Run method called")
if self._client.connect():
self.alive = True
else:
self.logger.error(f'Connection to {self.host}:{self.port} not possible, plugin not starting')

def handle_connect(self):
self._command(self._init_cmd, reply=False)
for mb in self._mailboxes:
mbc = self.mailbox_count(mb)
if mbc is not None:
self._mailboxes[mb](mbc[1])

def stop(self):
"""
Stop method for the plugin
"""
self.logger.debug("Stop method called")
if self._client.connected():
self._client.close()
self.alive = False
self._reply_lock.acquire()
self._reply_lock.notify()
self._reply_lock.release()
2 changes: 1 addition & 1 deletion asterisk/plugin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ plugin:
state: ready
documentation: https://www.smarthomeng.de/user/plugins/asterisk/README.html
support: https://knx-user-forum.de/forum/supportforen/smarthome-py/
version: 1.4.0 # Plugin version
version: 1.4.1 # Plugin version
sh_minversion: 1.9.0 # minimum shNG version to use this plugin
# sh_maxversion: # maximum shNG version to use this plugin (leave empty if latest)
# py_minversion: 3.6 # minimum Python version to use for this plugin
Expand Down

0 comments on commit 8f687e1

Please sign in to comment.