Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

smartplugin: add pause_item (instead of suspend item) #657

Merged
merged 7 commits into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions dev/sample_module/module.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ module:
# Global plugin attributes
classname: SampleModule
version: 1.0.0
sh_minversion: 1.8
# sh_maxversion: # maximum shNG version to use this module (leave empty if latest)
# py_minversion: 3.6 # minimum Python version to use for this module
# py_maxversion: # maximum Python version to use for this module (leave empty if latest)

# these min/max-versions MUST be given in quotes, or e.g. 3.10 will be interpreted as 3.1 (3.1 < 3.9 < 3.10)
sh_minversion: '1.10' # minimum shNG version to use this plugin
# sh_maxversion: '1.11' # maximum shNG version to use this plugin (omit if latest)
# py_minversion: '3.10' # minimum Python version to use for this plugin
# py_maxversion: '4.25' # maximum Python version to use for this plugin (omit if latest)

description:
de: 'Modul implementiert ...'
en: 'Module implements ...'
Expand Down
32 changes: 32 additions & 0 deletions dev/sample_mqttplugin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ def __init__(self, sh):
# Call init code of parent class (MqttPlugin)
super().__init__()

# if you want to use an item to toggle plugin execution, enable the
# definition in plugin.yaml and uncomment the following line
#self._pause_item_path = self.get_parameter_value('pause_item')
Morg42 marked this conversation as resolved.
Show resolved Hide resolved

# Initialization code goes here

# On initialization error use:
Expand All @@ -78,6 +82,10 @@ def run(self):

self.alive = True

# let the plugin change the state of pause_item
if self._pause_item:
Morg42 marked this conversation as resolved.
Show resolved Hide resolved
self._pause_item(False, self.get_fullname())

# start subscription to all topics
self.start_subscriptions()

Expand All @@ -88,6 +96,13 @@ def stop(self):
self.logger.dbghigh(self.translate("Methode '{method}' aufgerufen", {'method': 'stop()'}))
self.alive = False

# let the plugin change the state of pause_item
if self._pause_item:
self._pause_item(True, self.get_fullname())

# if you use schedulers, this stops all schedulers the plugin has started.
#self.scheduler_remove_all()
Morg42 marked this conversation as resolved.
Show resolved Hide resolved

# stop subscription to all topics
self.stop_subscriptions()

Expand All @@ -104,6 +119,13 @@ def parse_item(self, item):
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.
"""
# check for pause item
if item.property.path == self._pause_item_path:
self.logger.debug(f'pause item {item.property.path} registered')
self._pause_item = item
self.add_item(item, updating=True)
return self.update_item

if self.has_iattr(item.conf, 'foo_itemid'):
self.logger.debug(f"parse item: {item.property.path}")

Expand Down Expand Up @@ -148,6 +170,16 @@ def update_item(self, item, caller=None, source=None, dest=None):
:param source: if given it represents the source
:param dest: if given it represents the dest
"""
# check for pause item
if item is self._pause_item:
if caller != self.get_shortname():
self.logger.debug(f'pause item changed to {item()}')
if item() and self.alive:
self.stop()
elif not item() and not self.alive:
self.run()
return

if self.alive and caller != self.get_shortname():
# code to execute if the plugin is not stopped
# and only, if the item has not been changed by this this plugin:
Expand Down
24 changes: 13 additions & 11 deletions dev/sample_mqttplugin/plugin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,28 @@ plugin:
# support: https://knx-user-forum.de/forum/supportforen/smarthome-py

version: 1.0.0 # Plugin version
sh_minversion: 1.8 # 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
# py_maxversion: # maximum Python version to use for this plugin (leave empty if latest)

# these min/max-versions MUST be given in quotes, or e.g. 3.10 will be interpreted as 3.1 (3.1 < 3.9 < 3.10)
sh_minversion: '1.10' # minimum shNG version to use this plugin
# sh_maxversion: '1.11' # maximum shNG version to use this plugin (omit if latest)
# py_minversion: '3.10' # minimum Python version to use for this plugin
# py_maxversion: '4.25' # maximum Python version to use for this plugin (omit if latest)

multi_instance: false # plugin supports multi instance
restartable: unknown
suspendable: false # plugin can be suspended, must be implemented in code
restartable: unknown # plugin supports stopping and starting again, must be implemented
classname: SamplePlugin # class containing the plugin

parameters:
# Definition of parameters to be configured in etc/plugin.yaml (enter 'parameters: NONE', if section should be empty)

# item to toggle suspend mode
suspend_item:
# item to toggle plugin execution, remove if not wanted
# (needs plugin to be restartable)
pause_item:
type: str
default: ''
description:
de: 'Item zum Schalten des Suspend-Modus'
en: 'item for toggling suspend mode'

de: 'Item, um die Ausführung des Plugins zu steuern'
en: 'item for controlling plugin execution'

item_attributes:
# Definition of item attributes defined by this plugin (enter 'item_attributes: NONE', if section should be empty)
Expand Down
52 changes: 49 additions & 3 deletions dev/sample_plugin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ def __init__(self, sh):
# (maybe you want to make it a plugin parameter?)
# self._cycle = 60

# if you want to use an item to toggle plugin execution, enable the
# definition in plugin.yaml and uncomment the following line
#self._pause_item_path = self.get_parameter_value('pause_item')

# Initialization code goes here

# On initialization error use:
Expand All @@ -88,10 +92,16 @@ def run(self):
Run method for the plugin
"""
self.logger.dbghigh(self.translate("Methode '{method}' aufgerufen", {'method': 'run()'}))

# connect to network / web / serial device
# (enable the following lines if you want to open a connection
# don't forget to implement a connect (and disconnect) method.. :) )
#self.connect()

# setup scheduler for device poll loop
# (enable the following line, if you need to poll the device.
# Rember to un-comment the self._cycle statement in __init__ as well)
#self.scheduler_add('poll_device', self.poll_device, cycle=self._cycle)
#self.scheduler_add(self.get_fullname() + '_poll', self.poll_device, cycle=self._cycle)

# Start the asyncio eventloop in it's own thread
# and set self.alive to True when the eventloop is running
Expand All @@ -100,8 +110,15 @@ def run(self):

self.alive = True # if using asyncio, do not set self.alive here. Set it in the session coroutine

# let the plugin change the state of pause_item
if self._pause_item:
self._pause_item(False, self.get_fullname())

# if you need to create child threads, do not make them daemon = True!
# They will not shutdown properly. (It's a python bug)
# Also, don't create the thread in __init__() and start them here, but
# create and start them here. Threads can not be restarted after they
# have been stopped...

def stop(self):
"""
Expand All @@ -110,13 +127,25 @@ def stop(self):
self.logger.dbghigh(self.translate("Methode '{method}' aufgerufen", {'method': 'stop()'}))
self.alive = False # if using asyncio, do not set self.alive here. Set it in the session coroutine

# if you use a scheduled poll loop, enable the following line
#self.scheduler_remove('poll_device')
# let the plugin change the state of pause_item
if self._pause_item:
self._pause_item(True, self.get_fullname())

# this stops all schedulers the plugin has started.
# you can disable/delete the line if you don't use schedulers
self.scheduler_remove_all()

# stop the asyncio eventloop and it's thread
# If you use asyncio, enable the following line
#self.stop_asyncio()

# If you called connect() on run(), disconnect here
# (remember to write a disconnect() method!)
#self.disconnect()

# also, clean up anything you set up in run(), so the plugin can be
# cleanly stopped and started again

def parse_item(self, item):
"""
Default plugin parse_item method. Is called when the plugin is initialized.
Expand All @@ -130,6 +159,13 @@ def parse_item(self, item):
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.
"""
# check for pause item
if item.property.path == self._pause_item_path:
self.logger.debug(f'pause item {item.property.path} registered')
self._pause_item = item
self.add_item(item, updating=True)
return self.update_item

if self.has_iattr(item.conf, 'foo_itemtag'):
self.logger.debug(f"parse item: {item}")

Expand Down Expand Up @@ -163,6 +199,16 @@ def update_item(self, item, caller=None, source=None, dest=None):
:param source: if given it represents the source
:param dest: if given it represents the dest
"""
# check for pause item
if item is self._pause_item:
if caller != self.get_shortname():
self.logger.debug(f'pause item changed to {item()}')
if item() and self.alive:
self.stop()
elif not item() and not self.alive:
self.run()
return

if self.alive and caller != self.get_fullname():
# code to execute if the plugin is not stopped
# and only, if the item has not been changed by this plugin:
Expand Down
23 changes: 13 additions & 10 deletions dev/sample_plugin/plugin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,28 @@ plugin:
# support: https://knx-user-forum.de/forum/supportforen/smarthome-py

version: 1.0.0 # Plugin version (must match the version specified in __init__.py)
sh_minversion: 1.8 # 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
# py_maxversion: # maximum Python version to use for this plugin (leave empty if latest)

# these min/max-versions MUST be given in quotes, or e.g. 3.10 will be interpreted as 3.1 (3.1 < 3.9 < 3.10)
sh_minversion: '1.10' # minimum shNG version to use this plugin
# sh_maxversion: '1.11' # maximum shNG version to use this plugin (omit if latest)
# py_minversion: '3.10' # minimum Python version to use for this plugin
# py_maxversion: '4.25' # maximum Python version to use for this plugin (omit if latest)

multi_instance: false # plugin supports multi instance
restartable: unknown
suspendable: false # plugin can be suspended, must be implemented in code
restartable: unknown # plugin supports stopping and starting again, must be implemented
classname: SamplePlugin # class containing the plugin

parameters:
# Definition of parameters to be configured in etc/plugin.yaml (enter 'parameters: NONE', if section should be empty)

# item to toggle suspend mode
suspend_item:
# item to toggle plugin execution, remove if not wanted
# (needs plugin to be restartable)
pause_item:
type: str
default: ''
description:
de: 'Item zum Schalten des Suspend-Modus'
en: 'item for toggling suspend mode'
de: 'Item, um die Ausführung des Plugins zu steuern'
en: 'item for controlling plugin execution'

param1:
type: str
Expand Down
9 changes: 7 additions & 2 deletions dev/sample_smartdevice_plugin/plugin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,13 @@ plugin:
# documentation: https://github.com/smarthomeNG/smarthome/wiki/
# support: https://knx-user-forum.de/forum/supportforen/smarthome-py/
version: 0.0.1 # !! adjust
sh_minversion: 1.9.5
py_minversion: 3.6

# these min/max-versions MUST be given in quotes, or e.g. 3.10 will be interpreted as 3.1 (3.1 < 3.9 < 3.10)
sh_minversion: '1.10' # minimum shNG version to use this plugin
# sh_maxversion: '1.11' # maximum shNG version to use this plugin (omit if latest)
# py_minversion: '3.10' # minimum Python version to use for this plugin
# py_maxversion: '4.25' # maximum Python version to use for this plugin (omit if latest)

multi_instance: true
restartable: true
suspendable: true # plugin can be suspended, implemented in sdp
Expand Down
9 changes: 7 additions & 2 deletions dev/sample_smartdevice_standalone_plugin/plugin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,13 @@ plugin:
# documentation: https://github.com/smarthomeNG/smarthome/wiki/
# support: https://knx-user-forum.de/forum/supportforen/smarthome-py/
version: 0.0.1 # !! adjust
sh_minversion: 1.9.5
py_minversion: 3.6

# these min/max-versions MUST be given in quotes, or e.g. 3.10 will be interpreted as 3.1 (3.1 < 3.9 < 3.10)
sh_minversion: '1.10' # minimum shNG version to use this plugin
# sh_maxversion: '1.11' # maximum shNG version to use this plugin (omit if latest)
# py_minversion: '3.10' # minimum Python version to use for this plugin
# py_maxversion: '4.25' # maximum Python version to use for this plugin (omit if latest)

multi_instance: true
restartable: true
suspendable: true # plugin can be suspended, implemented in sdp
Expand Down
4 changes: 1 addition & 3 deletions lib/model/mqttplugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def __init__(self):
"""
Initialization Routine for the mqtt extension class to SmartPlugin
"""
SmartPlugin.__init__(self)
super().__init__()

# get instance of MQTT module
try:
Expand All @@ -60,8 +60,6 @@ def __init__(self):
# get broker configuration (for display in web interface)
self.broker_config = self.mod_mqtt.get_broker_config()

return True


def translate(self, txt, vars=None, block=None):
"""
Expand Down
Loading
Loading