Skip to content

Commit 99c249d

Browse files
authored
Merge pull request #78 from brefra/dynamic_load_timeout
Dynamic load timeout
2 parents 6160237 + fe27e1d commit 99c249d

File tree

3 files changed

+58
-16
lines changed

3 files changed

+58
-16
lines changed

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
setup(
44
name="python-velbus",
5-
version="2.1.3",
5+
version="2.1.4",
66
url="https://github.com/thomasdelaet/python-velbus",
77
license="MIT",
88
author="Thomas Delaet",

velbus/controller.py

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ def module_loaded():
153153
self._load_finished = True
154154
callback()
155155

156-
def timeout_expired():
156+
def final_timeout_expired():
157157
if not self._load_finished:
158158
modules_not_loaded = []
159159
for module in self._modules:
@@ -170,10 +170,33 @@ def timeout_expired():
170170
del self._modules[module]
171171
callback()
172172

173-
# 180 second timeout for loading modules
174-
self.load_timeout = threading.Timer(360, timeout_expired).start()
173+
def first_retry():
174+
if not self._load_finished:
175+
# First load failed, do 2nd retry for failed modules
176+
_missing_modules = 0
177+
for module in self._modules:
178+
if not self._modules[module].loaded:
179+
self.logger.warning(
180+
"Failed to load module "
181+
+ str(self._modules[module].get_module_name())
182+
+ " at address "
183+
+ str(self._modules[module].get_module_address())
184+
+ ", retry initiated."
185+
)
186+
# Trigger load without callback
187+
self._modules[module].load(None)
188+
_missing_modules += 1
189+
# Set final timeout
190+
threading.Timer(
191+
(_missing_modules * 10) + 1, final_timeout_expired
192+
).start()
193+
194+
# Set first timeout to 10 second for each module to trigger a retry
195+
threading.Timer((len(self._modules) * 10) + 1, first_retry).start()
196+
175197
for module in self._modules:
176198
self._modules[module].load(module_loaded)
199+
time.sleep(1) # Throttle loading modules
177200

178201
for address in range(0, 256):
179202
message = ModuleTypeRequestMessage(address)

velbus/module.py

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import string
55
import struct
66
from velbus.messages.read_data_from_memory import ReadDataFromMemoryMessage
7+
from datetime import datetime, timedelta
78
from velbus.messages.memory_data import MemoryDataMessage
89
from velbus.messages.channel_name_part1 import ChannelNamePart1Message
910
from velbus.messages.channel_name_part1 import ChannelNamePart1Message2
@@ -39,7 +40,9 @@ def __init__(self, module_type, module_name, module_address, controller):
3940

4041
self._loaded_callbacks = []
4142
self.loaded = False
43+
self._loading_triggered = False
4244

45+
self._last_channel_name_msg = datetime.utcnow()
4346
self._controller = controller
4447
self._controller.subscribe(self.on_message)
4548

@@ -148,18 +151,33 @@ def load(self, callback):
148151
"""
149152
Retrieve names of channels
150153
"""
151-
if not self._is_submodule():
152-
# load the data from memory ( the stuff that we need)
153-
self._load_memory()
154-
# load the module status
155-
self._request_module_status()
156-
if not self._is_submodule():
157-
# load the channel names
158-
self._request_channel_name()
159-
if callback:
160-
self._loaded_callbacks.append(callback)
161-
# load the module specific stuff
162-
self._load()
154+
if not self.loaded:
155+
if not self._loading_triggered:
156+
self._loading_triggered = True
157+
if not self._is_submodule():
158+
# load the data from memory ( the stuff that we need)
159+
self._load_memory()
160+
# load the module status
161+
self._request_module_status()
162+
if not self._is_submodule():
163+
# load the channel names
164+
self._request_channel_name()
165+
# load the module specific stuff
166+
self._load()
167+
else:
168+
# Request channel names if last received
169+
if (
170+
not self._is_submodule()
171+
and not self._name_messages_complete()
172+
and self._last_channel_name_msg
173+
< datetime.utcnow() - timedelta(seconds=10)
174+
):
175+
self._request_channel_name()
176+
if callback:
177+
self._loaded_callbacks.append(callback)
178+
else:
179+
if callback:
180+
callback()
163181

164182
def loading_in_progress(self):
165183
return not self._name_messages_complete()
@@ -185,6 +203,7 @@ def _name_count_needed(self):
185203
return self.number_of_channels() * 3
186204

187205
def _process_channel_name_message(self, part, message):
206+
self._last_channel_name_msg = datetime.utcnow()
188207
channel = message.channel
189208
if self._is_submodule():
190209
channel = channel - (self.number_of_channels() * self.sub_module)

0 commit comments

Comments
 (0)