Added deprecation notice for `zwave` plugin and backend (use `zwave.mqtt` instead)

This commit is contained in:
Fabio Manganiello 2022-10-22 19:17:58 +02:00
parent 5c68365188
commit 1af7ece881
Signed by: blacklight
GPG Key ID: D90FBA7F76362774
2 changed files with 162 additions and 70 deletions

View File

@ -8,13 +8,33 @@ from typing import Optional
from platypush.backend import Backend from platypush.backend import Backend
from platypush.config import Config from platypush.config import Config
from platypush.message.event.zwave import ZwaveNetworkReadyEvent, ZwaveNetworkStoppedEvent, ZwaveEvent, \ from platypush.message.event.zwave import (
ZwaveNodeAddedEvent, ZwaveValueAddedEvent, ZwaveNodeQueryCompletedEvent, ZwaveValueChangedEvent, \ ZwaveNetworkReadyEvent,
ZwaveValueRefreshedEvent, ZwaveValueRemovedEvent, ZwaveNetworkResetEvent, ZwaveCommandEvent, \ ZwaveNetworkStoppedEvent,
ZwaveCommandWaitingEvent, ZwaveNodeRemovedEvent, ZwaveNodeRenamedEvent, ZwaveNodeReadyEvent, \ ZwaveEvent,
ZwaveButtonRemovedEvent, ZwaveButtonCreatedEvent, ZwaveButtonOnEvent, ZwaveButtonOffEvent, ZwaveNetworkErrorEvent, \ ZwaveNodeAddedEvent,
ZwaveNodeGroupEvent, ZwaveNodePollingEnabledEvent, ZwaveNodePollingDisabledEvent, ZwaveNodeSceneEvent, \ ZwaveValueAddedEvent,
ZwaveNodeEvent ZwaveNodeQueryCompletedEvent,
ZwaveValueChangedEvent,
ZwaveValueRefreshedEvent,
ZwaveValueRemovedEvent,
ZwaveNetworkResetEvent,
ZwaveCommandEvent,
ZwaveCommandWaitingEvent,
ZwaveNodeRemovedEvent,
ZwaveNodeRenamedEvent,
ZwaveNodeReadyEvent,
ZwaveButtonRemovedEvent,
ZwaveButtonCreatedEvent,
ZwaveButtonOnEvent,
ZwaveButtonOffEvent,
ZwaveNetworkErrorEvent,
ZwaveNodeGroupEvent,
ZwaveNodePollingEnabledEvent,
ZwaveNodePollingDisabledEvent,
ZwaveNodeSceneEvent,
ZwaveNodeEvent,
)
event_queue = queue.Queue() event_queue = queue.Queue()
network_ready = threading.Event() network_ready = threading.Event()
@ -52,6 +72,14 @@ class ZwaveBackend(Backend):
# Restart the udev service # Restart the udev service
systemctl restart systemd-udevd.service systemctl restart systemd-udevd.service
.. note::
This backend is deprecated, since the underlying ``python-openzwave`` is
quite buggy and largely unmaintained.
Use the `zwave.mqtt` backend instead
(:class:`platypush.backend.zwave.mqtt.ZwaveMqttBackend`).
Triggers: Triggers:
* :class:`platypush.message.event.zwave.ZwaveNetworkReadyEvent` when the network is up and running. * :class:`platypush.message.event.zwave.ZwaveNetworkReadyEvent` when the network is up and running.
@ -93,8 +121,15 @@ class ZwaveBackend(Backend):
""" """
def __init__(self, device: str, config_path: Optional[str] = None, user_path: Optional[str] = None, def __init__(
ready_timeout: float = 10.0, *args, **kwargs): self,
device: str,
config_path: Optional[str] = None,
user_path: Optional[str] = None,
ready_timeout: float = 10.0,
*args,
**kwargs
):
""" """
:param device: Path to the Z-Wave adapter (e.g. /dev/ttyUSB0 or /dev/ttyACM0). :param device: Path to the Z-Wave adapter (e.g. /dev/ttyUSB0 or /dev/ttyACM0).
:param config_path: Z-Wave configuration path (default: ``<OPENZWAVE_PATH>/ozw_config``). :param config_path: Z-Wave configuration path (default: ``<OPENZWAVE_PATH>/ozw_config``).
@ -110,7 +145,9 @@ class ZwaveBackend(Backend):
if not config_path: if not config_path:
# noinspection PyTypeChecker # noinspection PyTypeChecker
config_path = os.path.join(os.path.dirname(inspect.getfile(python_openzwave)), 'ozw_config') config_path = os.path.join(
os.path.dirname(inspect.getfile(python_openzwave)), 'ozw_config'
)
if not user_path: if not user_path:
user_path = os.path.join(Config.get('workdir'), 'zwave') user_path = os.path.join(Config.get('workdir'), 'zwave')
os.makedirs(user_path, mode=0o770, exist_ok=True) os.makedirs(user_path, mode=0o770, exist_ok=True)
@ -130,7 +167,9 @@ class ZwaveBackend(Backend):
network_ready.clear() network_ready.clear()
logging.getLogger('openzwave').addHandler(self.logger) logging.getLogger('openzwave').addHandler(self.logger)
opts = ZWaveOption(self.device, config_path=self.config_path, user_path=self.user_path) opts = ZWaveOption(
self.device, config_path=self.config_path, user_path=self.user_path
)
opts.set_console_output(False) opts.set_console_output(False)
opts.lock() opts.lock()
@ -139,7 +178,11 @@ class ZwaveBackend(Backend):
ready = network_ready.wait(self.ready_timeout) ready = network_ready.wait(self.ready_timeout)
if not ready: if not ready:
self.logger.warning('Driver not ready after {} seconds: continuing anyway'.format(self.ready_timeout)) self.logger.warning(
'Driver not ready after {} seconds: continuing anyway'.format(
self.ready_timeout
)
)
def stop_network(self): def stop_network(self):
if self.network: if self.network:
@ -149,47 +192,72 @@ class ZwaveBackend(Backend):
def _process_event(self, event: _ZWEvent): def _process_event(self, event: _ZWEvent):
from platypush.plugins.zwave import ZwavePlugin from platypush.plugins.zwave import ZwavePlugin
network = event.network if hasattr(event, 'network') and event.network else self.network
if event.signal == network.SIGNAL_NETWORK_STOPPED or \ network = (
event.signal == network.SIGNAL_DRIVER_REMOVED: event.network
if hasattr(event, 'network') and event.network
else self.network
)
if (
event.signal == network.SIGNAL_NETWORK_STOPPED
or event.signal == network.SIGNAL_DRIVER_REMOVED
):
event = ZwaveNetworkStoppedEvent(device=self.device) event = ZwaveNetworkStoppedEvent(device=self.device)
elif event.signal == network.SIGNAL_ALL_NODES_QUERIED or \ elif (
event.signal == network.SIGNAL_ALL_NODES_QUERIED_SOME_DEAD: event.signal == network.SIGNAL_ALL_NODES_QUERIED
or event.signal == network.SIGNAL_ALL_NODES_QUERIED_SOME_DEAD
):
event = ZwaveNodeQueryCompletedEvent(device=self.device) event = ZwaveNodeQueryCompletedEvent(device=self.device)
elif event.signal == network.SIGNAL_NETWORK_FAILED: elif event.signal == network.SIGNAL_NETWORK_FAILED:
event = ZwaveNetworkErrorEvent(device=self.device) event = ZwaveNetworkErrorEvent(device=self.device)
self.logger.warning('Z-Wave network error') self.logger.warning('Z-Wave network error')
elif event.signal == network.SIGNAL_NETWORK_RESETTED or \ elif (
event.signal == network.SIGNAL_DRIVER_RESET: event.signal == network.SIGNAL_NETWORK_RESETTED
or event.signal == network.SIGNAL_DRIVER_RESET
):
event = ZwaveNetworkResetEvent(device=self.device) event = ZwaveNetworkResetEvent(device=self.device)
elif event.signal == network.SIGNAL_BUTTON_ON: elif event.signal == network.SIGNAL_BUTTON_ON:
event = ZwaveButtonOnEvent(device=self.device, event = ZwaveButtonOnEvent(
node=ZwavePlugin.node_to_dict(event.args['node'])) device=self.device, node=ZwavePlugin.node_to_dict(event.args['node'])
)
elif event.signal == network.SIGNAL_BUTTON_OFF: elif event.signal == network.SIGNAL_BUTTON_OFF:
event = ZwaveButtonOffEvent(device=self.device, event = ZwaveButtonOffEvent(
node=ZwavePlugin.node_to_dict(event.args['node'])) device=self.device, node=ZwavePlugin.node_to_dict(event.args['node'])
)
elif event.signal == network.SIGNAL_CONTROLLER_COMMAND: elif event.signal == network.SIGNAL_CONTROLLER_COMMAND:
event = ZwaveCommandEvent(device=self.device, event = ZwaveCommandEvent(
state=event.args['state'], device=self.device,
state_description=event.args['state_full'], state=event.args['state'],
error=event.args['error'] if event.args['error_int'] else None, state_description=event.args['state_full'],
error_description=event.args['error_full'] if event.args['error_int'] else None, error=event.args['error'] if event.args['error_int'] else None,
node=ZwavePlugin.node_to_dict(event.args['node']) if event.args['node'] else None) error_description=event.args['error_full']
if event.args['error_int']
else None,
node=ZwavePlugin.node_to_dict(event.args['node'])
if event.args['node']
else None,
)
elif event.signal == network.SIGNAL_CONTROLLER_WAITING: elif event.signal == network.SIGNAL_CONTROLLER_WAITING:
event = ZwaveCommandWaitingEvent(device=self.device, event = ZwaveCommandWaitingEvent(
state=event.args['state'], device=self.device,
state_description=event.args['state_full']) state=event.args['state'],
state_description=event.args['state_full'],
)
elif event.signal == network.SIGNAL_CREATE_BUTTON: elif event.signal == network.SIGNAL_CREATE_BUTTON:
event = ZwaveButtonCreatedEvent(device=self.device, event = ZwaveButtonCreatedEvent(
node=ZwavePlugin.node_to_dict(event.args['node'])) device=self.device, node=ZwavePlugin.node_to_dict(event.args['node'])
)
elif event.signal == network.SIGNAL_DELETE_BUTTON: elif event.signal == network.SIGNAL_DELETE_BUTTON:
event = ZwaveButtonRemovedEvent(device=self.device, event = ZwaveButtonRemovedEvent(
node=ZwavePlugin.node_to_dict(event.args['node'])) device=self.device, node=ZwavePlugin.node_to_dict(event.args['node'])
)
elif event.signal == network.SIGNAL_GROUP: elif event.signal == network.SIGNAL_GROUP:
event = ZwaveNodeGroupEvent(device=self.device, event = ZwaveNodeGroupEvent(
node=ZwavePlugin.node_to_dict(event.args['node']), device=self.device,
group_index=event.args['groupidx']) node=ZwavePlugin.node_to_dict(event.args['node']),
group_index=event.args['groupidx'],
)
elif event.signal == network.SIGNAL_NETWORK_AWAKED: elif event.signal == network.SIGNAL_NETWORK_AWAKED:
event = ZwaveNetworkReadyEvent( event = ZwaveNetworkReadyEvent(
device=self.device, device=self.device,
@ -202,46 +270,63 @@ class ZwaveBackend(Backend):
nodes_count=self.network.nodes_count, nodes_count=self.network.nodes_count,
) )
elif event.signal == network.SIGNAL_NODE_EVENT: elif event.signal == network.SIGNAL_NODE_EVENT:
event = ZwaveNodeEvent(device=self.device, event = ZwaveNodeEvent(
node=ZwavePlugin.node_to_dict(event.args['node'])) device=self.device, node=ZwavePlugin.node_to_dict(event.args['node'])
)
elif event.signal == network.SIGNAL_NODE_ADDED: elif event.signal == network.SIGNAL_NODE_ADDED:
event = ZwaveNodeAddedEvent(device=self.device, event = ZwaveNodeAddedEvent(
node=ZwavePlugin.node_to_dict(event.args['node'])) device=self.device, node=ZwavePlugin.node_to_dict(event.args['node'])
)
elif event.signal == network.SIGNAL_NODE_NAMING: elif event.signal == network.SIGNAL_NODE_NAMING:
event = ZwaveNodeRenamedEvent(device=self.device, event = ZwaveNodeRenamedEvent(
node=ZwavePlugin.node_to_dict(event.args['node'])) device=self.device, node=ZwavePlugin.node_to_dict(event.args['node'])
)
elif event.signal == network.SIGNAL_NODE_READY: elif event.signal == network.SIGNAL_NODE_READY:
event = ZwaveNodeReadyEvent(device=self.device, event = ZwaveNodeReadyEvent(
node=ZwavePlugin.node_to_dict(event.args['node'])) device=self.device, node=ZwavePlugin.node_to_dict(event.args['node'])
)
elif event.signal == network.SIGNAL_NODE_REMOVED: elif event.signal == network.SIGNAL_NODE_REMOVED:
event = ZwaveNodeRemovedEvent(device=self.device, event = ZwaveNodeRemovedEvent(
node=ZwavePlugin.node_to_dict(event.args['node'])) device=self.device, node=ZwavePlugin.node_to_dict(event.args['node'])
)
elif event.signal == network.SIGNAL_POLLING_DISABLED: elif event.signal == network.SIGNAL_POLLING_DISABLED:
event = ZwaveNodePollingEnabledEvent(device=self.device, event = ZwaveNodePollingEnabledEvent(
node=ZwavePlugin.node_to_dict(event.args['node'])) device=self.device, node=ZwavePlugin.node_to_dict(event.args['node'])
)
elif event.signal == network.SIGNAL_POLLING_ENABLED: elif event.signal == network.SIGNAL_POLLING_ENABLED:
event = ZwaveNodePollingDisabledEvent(device=self.device, event = ZwaveNodePollingDisabledEvent(
node=ZwavePlugin.node_to_dict(event.args['node'])) device=self.device, node=ZwavePlugin.node_to_dict(event.args['node'])
)
elif event.signal == network.SIGNAL_SCENE_EVENT: elif event.signal == network.SIGNAL_SCENE_EVENT:
event = ZwaveNodeSceneEvent(device=self.device, event = ZwaveNodeSceneEvent(
scene_id=event.args['scene_id'], device=self.device,
node=ZwavePlugin.node_to_dict(event.args['node'])) scene_id=event.args['scene_id'],
node=ZwavePlugin.node_to_dict(event.args['node']),
)
elif event.signal == network.SIGNAL_VALUE_ADDED: elif event.signal == network.SIGNAL_VALUE_ADDED:
event = ZwaveValueAddedEvent(device=self.device, event = ZwaveValueAddedEvent(
node=ZwavePlugin.node_to_dict(event.args['node']), device=self.device,
value=ZwavePlugin.value_to_dict(event.args['value'])) node=ZwavePlugin.node_to_dict(event.args['node']),
value=ZwavePlugin.value_to_dict(event.args['value']),
)
elif event.signal == network.SIGNAL_VALUE_CHANGED: elif event.signal == network.SIGNAL_VALUE_CHANGED:
event = ZwaveValueChangedEvent(device=self.device, event = ZwaveValueChangedEvent(
node=ZwavePlugin.node_to_dict(event.args['node']), device=self.device,
value=ZwavePlugin.value_to_dict(event.args['value'])) node=ZwavePlugin.node_to_dict(event.args['node']),
value=ZwavePlugin.value_to_dict(event.args['value']),
)
elif event.signal == network.SIGNAL_VALUE_REFRESHED: elif event.signal == network.SIGNAL_VALUE_REFRESHED:
event = ZwaveValueRefreshedEvent(device=self.device, event = ZwaveValueRefreshedEvent(
node=ZwavePlugin.node_to_dict(event.args['node']), device=self.device,
value=ZwavePlugin.value_to_dict(event.args['value'])) node=ZwavePlugin.node_to_dict(event.args['node']),
value=ZwavePlugin.value_to_dict(event.args['value']),
)
elif event.signal == network.SIGNAL_VALUE_REMOVED: elif event.signal == network.SIGNAL_VALUE_REMOVED:
event = ZwaveValueRemovedEvent(device=self.device, event = ZwaveValueRemovedEvent(
node=ZwavePlugin.node_to_dict(event.args['node']), device=self.device,
value=ZwavePlugin.value_to_dict(event.args['value'])) node=ZwavePlugin.node_to_dict(event.args['node']),
value=ZwavePlugin.value_to_dict(event.args['value']),
)
else: else:
self.logger.info('Received unhandled ZWave event: {}'.format(event)) self.logger.info('Received unhandled ZWave event: {}'.format(event))

View File

@ -3,15 +3,22 @@ from typing import Any, Dict, Optional, List, Union
from platypush.backend.zwave import ZwaveBackend from platypush.backend.zwave import ZwaveBackend
from platypush.context import get_backend from platypush.context import get_backend
from platypush.plugins import action from platypush.plugins import action
from platypush.plugins.switch import SwitchPlugin
from platypush.plugins.zwave._base import ZwaveBasePlugin from platypush.plugins.zwave._base import ZwaveBasePlugin
class ZwavePlugin(ZwaveBasePlugin, SwitchPlugin): class ZwavePlugin(ZwaveBasePlugin):
""" """
This plugin interacts with the devices on a Z-Wave network started through the This plugin interacts with the devices on a Z-Wave network started through the
:class:`platypush.backend.zwave.ZwaveBackend` backend. :class:`platypush.backend.zwave.ZwaveBackend` backend.
.. note::
This plugin is deprecated, since the underlying ``python-openzwave`` is
quite buggy and largely unmaintained.
Use the `zwave.mqtt` plugin instead
(:class:`platypush.plugins.zwave.mqtt.ZwaveMqttPlugin`).
Requires: Requires:
* **python-openzwave** (``pip install python-openzwave``) * **python-openzwave** (``pip install python-openzwave``)