From 74f448978a72a05ecfe6851495b4f86325fd0795 Mon Sep 17 00:00:00 2001 From: Kevin Robert Keegan Date: Wed, 13 Nov 2024 16:32:03 -0800 Subject: [PATCH 1/3] Remove Battery Devices from *_all Commands If they are present, the sequence for the *_all command will halt when it gets to a battery device and only resume when that device has woken up and the command was sent. This is at best confusing to the user, because they expect to see the sequence run to completion and receive a message like "Refresh All Devices Complete" At worst, this is problematic if a device after a battery device in the sequence is not getting the proper command and the user assumes that it is. --- insteon_mqtt/Modem.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/insteon_mqtt/Modem.py b/insteon_mqtt/Modem.py index dc1c2ab8..b20fa345 100644 --- a/insteon_mqtt/Modem.py +++ b/insteon_mqtt/Modem.py @@ -10,6 +10,7 @@ from .const import __version__ from .Address import Address from .CommandSeq import CommandSeq +from .device.BatterySensor import BatterySensor from . import config from . import db from . import handler @@ -453,7 +454,8 @@ def refresh_all(self, force=False, on_done=None): # Reload all the device databases. for device in self.devices.values(): - seq.add(device.refresh, force) + if (not isinstance(device, BatterySensor)): + seq.add(device.refresh, force) # Start the command sequence. seq.run() @@ -478,7 +480,8 @@ def get_engine_all(self, on_done=None): # Reload all the device databases. for device in self.devices.values(): - seq.add(device.get_engine) + if (not isinstance(device, BatterySensor)): + seq.add(device.get_engine) # Start the command sequence. seq.run() @@ -501,7 +504,8 @@ def join_all(self, on_done=None): # Join all the device databases. for device in self.devices.values(): - seq.add(device.join) + if (not isinstance(device, BatterySensor)): + seq.add(device.join) # Start the command sequence. seq.run() @@ -524,7 +528,8 @@ def pair_all(self, on_done=None): # Pair all the device databases. for device in self.devices.values(): - seq.add(device.pair) + if (not isinstance(device, BatterySensor)): + seq.add(device.pair) # Start the command sequence. seq.run() @@ -894,7 +899,8 @@ def sync_all(self, dry_run=True, refresh=True, on_done=None): # Then each other device. for device in self.devices.values(): - seq.add(device.sync, dry_run=dry_run, refresh=refresh) + if (not isinstance(device, BatterySensor)): + seq.add(device.sync, dry_run=dry_run, refresh=refresh) # Start the command sequence. seq.run() @@ -978,7 +984,8 @@ def import_scenes_all(self, dry_run=True, on_done=None): # Then each other device. for device in self.devices.values(): - group.add(device.import_scenes, dry_run=dry_run, save=False) + if (not isinstance(device, BatterySensor)): + group.add(device.import_scenes, dry_run=dry_run, save=False) # Save everything at the end if not dry_run: From 0ea83f6a2f35ab3e8083c391823100e7bca9c255 Mon Sep 17 00:00:00 2001 From: Kevin Robert Keegan Date: Wed, 13 Nov 2024 16:48:42 -0800 Subject: [PATCH 2/3] Add Documentation re Battery Devices and *_all Commands --- docs/battery_devices.md | 3 +++ docs/initializing.md | 11 +++++++---- docs/mqtt.md | 4 +++- docs/scenes.md | 8 ++++++-- insteon_mqtt/Modem.py | 18 ++++++++++++++++++ 5 files changed, 37 insertions(+), 7 deletions(-) diff --git a/docs/battery_devices.md b/docs/battery_devices.md index d846f5ae..018d8a03 100644 --- a/docs/battery_devices.md +++ b/docs/battery_devices.md @@ -4,6 +4,9 @@ Battery devices (e.g. motion sensors, remotes, etc) are normally sleeping and wi > As noted below, not all devices enter an _awake_ state after sending a message. For some devices, the only option is to manually wake them up. +## `*_all` Commands +None of the `*_all` style commands will work on battery devices, you must individually call the commands you wish to run on each battery device. + ## Waking a Battery Device ### Automatically diff --git a/docs/initializing.md b/docs/initializing.md index a8261514..c858ccb0 100644 --- a/docs/initializing.md +++ b/docs/initializing.md @@ -6,7 +6,7 @@ When setting up Insteon-MQTT, adding a new device, or to solve problems, it is n All of these functions are idempotent, they can be run multiple times without causing any issue. -> __Note__ Battery devices (e.g. motion sensors, remotes, etc) are normally sleeping and will not respond to commands sent to them. If the commands below are sent to a battery device, the command will be queued and will attempt to be run the next time the device is awake. For more details, see [battery devices](battery_devices.md) +> __Note__ Battery devices (e.g. motion sensors, remotes, etc) are normally sleeping and will not respond to commands sent to them. If the commands below are sent to a battery device, the command will be queued and will attempt to be run the next time the device is awake. None of the `*_all` commands will work on battery devices, you must individually call each desired command on battery devices. For more details, see [battery devices](battery_devices.md) 1. __Join__ This is necessary to allow the modem to talk to the device. This needs to be done first on any new device or device that has been factory reset. If you are seeing the error `Senders ID not in responders db. Try running 'join' again.` - To join a __single device__ run `join`. @@ -21,7 +21,8 @@ All of these functions are idempotent, they can be run multiple times without ca Payload: { "cmd" : "join" } ``` - - To join __all__ devices run `join_all`. This may be necesary when first setting up a network. + - To join __all__ non-battery devices run `join_all`. This may be necesary when first setting up a network. + - The `join` must be run individually on each desired battery device. _Command Line_ ``` @@ -47,7 +48,8 @@ All of these functions are idempotent, they can be run multiple times without ca Payload: { "cmd" : "pair" } ``` - - To pair __all__ devices run `pair_all`. This may be necesary when first setting up a network. + - To pair __all__ non_battery devices run `pair_all`. This may be necessary when first setting up a network. + - The `pair` must be run individually on each desired battery device. _Command Line_ ``` @@ -79,7 +81,8 @@ All of these functions are idempotent, they can be run multiple times without ca Payload: { "cmd" : "refresh", ["force" : true/false] } ``` - - To refresh __all__ devices run `refresh_all`. This may be necesary when first setting up a network. __This may take a while to complete__ + - To refresh __all__ non-battery devices run `refresh_all`. This may be necessary when first setting up a network. __This may take a while to complete__ + - This `refresh` must be run individually on each desired battery device. _Command Line_ ``` diff --git a/docs/mqtt.md b/docs/mqtt.md index 57788316..b95a6c28 100644 --- a/docs/mqtt.md +++ b/docs/mqtt.md @@ -223,13 +223,15 @@ data. Supported: modem -This will cause a get_engine command to be sent to each device (i.e. devices +This will cause a get_engine command to be sent to each non-battery device (i.e. devices defined in the config file). The command payload is: ``` { "cmd" : "get_engine_all"} ``` +This command must be run individually on each desired battery device. + ### Add the device as a controller of another device. Supported: modem, devices diff --git a/docs/scenes.md b/docs/scenes.md index ef07fbc4..0863f73f 100644 --- a/docs/scenes.md +++ b/docs/scenes.md @@ -101,7 +101,9 @@ The `import-scenes` function will attempt to keep the order and all comments in ``` ### `import-scenes-all` -The `import-scenes-all` function will perform the `import-scenes` function on all devices in the network. The same caveats about `import-scenes` apply to this function as well. +The `import-scenes-all` function will perform the `import-scenes` function on all non-battery devices in the network. The same caveats about `import-scenes` apply to this function as well. + +This command must be run individually on each desired battery device. > The `import-scenes-all` function can take quite a while to complete particularly if you have a lot of devices and scenes and/or a slow computer. For reference 85 devices on a raspberry pi takes about 20 seconds to complete. This may cause the command line to time out before the command completes. The command should continue to run and complete in the background however, you will not see the results printed to the screen. You can solve this by editing the file (../insteon_mqtt/cmd_line/util.py) and changing the line at the top from `TIME_OUT = 10` to something like `TIME_OUT = 30`. @@ -140,7 +142,9 @@ The changes will only be made to the device on which this command is called. So ``` ### `sync-all` -The `sync-all` function will perform the `sync` function on all devices in the network. The same caveats about `sync` apply to this function as well. +The `sync-all` function will perform the `sync` function on all non-battery devices in the network. The same caveats about `sync` apply to this function as well. + +This command must be run individually on each desired battery device. _Command Line_ ``` diff --git a/insteon_mqtt/Modem.py b/insteon_mqtt/Modem.py index b20fa345..f7fedb7e 100644 --- a/insteon_mqtt/Modem.py +++ b/insteon_mqtt/Modem.py @@ -437,6 +437,9 @@ def refresh_all(self, force=False, on_done=None): the database sizes. So it usually should only be called if no other activity is expected on the network. + Battery devices are not included in this command and this command + must be run individually on each battery device. + Args: force (bool): Force flag passed to devices. If True, devices will refresh their Insteon db's even if they think the db @@ -469,6 +472,9 @@ def get_engine_all(self, on_done=None): lose your data directory. Otherwise you likely never need to use this. + Battery devices are not included in this command and this command + must be run individually on each battery device. + Args: on_done: Finished callback. This is called when the command has completed. Signature is: on_done(success, msg, data) @@ -493,6 +499,9 @@ def join_all(self, on_done=None): This calls join on all the devices. This can take a little time. It is helpful when first setting up a network or replacing a PLM. + Battery devices are not included in this command and this command + must be run individually on each battery device. + Args: on_done: Finished callback. This is called when the command has completed. Signature is: on_done(success, msg, data) @@ -517,6 +526,9 @@ def pair_all(self, on_done=None): This calls pair on all the devices. This can take a little time. It is helpful when first setting up a network or replacing a PLM. + Battery devices are not included in this command and this command + must be run individually on each battery device. + Args: on_done: Finished callback. This is called when the command has completed. Signature is: on_done(success, msg, data) @@ -879,6 +891,9 @@ def _sync_add(self, entry, dry_run, on_done=None): def sync_all(self, dry_run=True, refresh=True, on_done=None): """Perform the 'sync' command on all devices. + Battery devices are not included in this command and this command + must be run individually on each battery device. + See the 'sync' command for a description. Args: @@ -964,6 +979,9 @@ def import_scenes(self, dry_run=True, save=True, on_done=None): def import_scenes_all(self, dry_run=True, on_done=None): """Perform the 'import_scenes' command on all devices. + Battery devices are not included in this command and this command + must be run individually on each battery device. + See the 'import_scenes' command for a description. Args: From 98f29ad2d916870f347e364e6e49513af64ea082 Mon Sep 17 00:00:00 2001 From: Kevin Robert Keegan Date: Thu, 14 Nov 2024 11:34:26 -0800 Subject: [PATCH 3/3] Fix Code Comment Co-authored-by: tstabrawa <59430211+tstabrawa@users.noreply.github.com> --- insteon_mqtt/Modem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/insteon_mqtt/Modem.py b/insteon_mqtt/Modem.py index f7fedb7e..215de5f5 100644 --- a/insteon_mqtt/Modem.py +++ b/insteon_mqtt/Modem.py @@ -484,7 +484,7 @@ def get_engine_all(self, on_done=None): seq = CommandSeq(self, "Get Engine all complete", on_done, error_stop=False, name="EngineAll") - # Reload all the device databases. + # Run Get Engine on all the devices for device in self.devices.values(): if (not isinstance(device, BatterySensor)): seq.add(device.get_engine)