--- a/controls/DebugVariablePanel/DebugVariableItem.py Tue Oct 19 13:09:45 2021 +0200
+++ b/controls/DebugVariablePanel/DebugVariableItem.py Wed Oct 20 08:57:07 2021 +0200
@@ -144,7 +144,7 @@
"""
# Return immediately if data empty or none
if self.Data is None or self.Data.count == 0:
- return None
+ return []
# Find nearest data outside given range indexes
start_idx = (self.GetNearestData(start_tick, -1)
--- a/graphics/GraphicCommons.py Tue Oct 19 13:09:45 2021 +0200
+++ b/graphics/GraphicCommons.py Wed Oct 20 08:57:07 2021 +0200
@@ -1063,6 +1063,8 @@
# Returns the RedrawRect
def GetRedrawRect(self, movex=0, movey=0):
+ if self.ParentBlock == None:
+ return None
parent_pos = self.ParentBlock.GetPosition()
x = min(parent_pos[0] + self.Pos.x, parent_pos[0] + self.Pos.x + self.Direction[0] * CONNECTOR_SIZE)
y = min(parent_pos[1] + self.Pos.y, parent_pos[1] + self.Pos.y + self.Direction[1] * CONNECTOR_SIZE)
--- a/graphics/LD_Objects.py Tue Oct 19 13:09:45 2021 +0200
+++ b/graphics/LD_Objects.py Wed Oct 20 08:57:07 2021 +0200
@@ -405,6 +405,8 @@
if self.Value is None:
self.Value = False
spreading = self.Input.ReceivingCurrent()
+ if spreading == "undefined":
+ spreading = False
if self.Type == CONTACT_NORMAL:
spreading &= self.Value
elif self.Type == CONTACT_REVERSE:
--- a/runtime/WampClient.py Tue Oct 19 13:09:45 2021 +0200
+++ b/runtime/WampClient.py Wed Oct 20 08:57:07 2021 +0200
@@ -75,7 +75,14 @@
"ID": "wamptest",
"active": False,
"realm": "Automation",
- "url": "ws://127.0.0.1:8888"
+ "url": "ws://127.0.0.1:8888",
+ "clientFactoryOptions": {
+ "maxDelay": 300
+ },
+ "protocolOptions": {
+ "autoPingInterval": 10,
+ "autoPingTimeout": 5
+ }
}
# Those two lists are meant to be filled by customized runtime
@@ -162,6 +169,14 @@
WampWebSocketClientFactory.__init__(self, *args, **kwargs)
try:
+ clientFactoryOptions = config.extra.get("clientFactoryOptions")
+ if clientFactoryOptions:
+ self.setClientFactoryOptions(clientFactoryOptions)
+ except Exception as e:
+ print(_("Custom client factory options failed : "), e)
+ _transportFactory = None
+
+ try:
protocolOptions = config.extra.get('protocolOptions', None)
if protocolOptions:
self.setProtocolOptions(**protocolOptions)
@@ -170,6 +185,11 @@
print(_("Custom protocol options failed :"), e)
_transportFactory = None
+ def setClientFactoryOptions(self, options):
+ for key, value in options.items():
+ if key in ["maxDelay", "initialDelay", "maxRetries", "factor", "jitter"]:
+ setattr(self, key, value)
+
def buildProtocol(self, addr):
self.resetDelay()
return ReconnectingClientFactory.buildProtocol(self, addr)
@@ -194,6 +214,9 @@
{"url": "Invalid URL: {}".format(url)},
_("WAMP configuration error:"))
+def UpdateWithDefault(d1, d2):
+ for k, v in d2.items():
+ d1.setdefault(k, v)
def GetConfiguration():
global lastKnownConfig
@@ -203,6 +226,7 @@
if os.path.exists(_WampConf):
try:
WampClientConf = json.load(open(_WampConf))
+ UpdateWithDefault(WampClientConf, defaultWampConfig)
except ValueError:
pass
@@ -320,7 +344,9 @@
def StartReconnectWampClient():
if _WampSession:
- # do reconnect
+ # do reconnect and reset continueTrying and initialDelay parameter
+ if _transportFactory is not None:
+ _transportFactory.resetDelay()
_WampSession.disconnect()
return True
else:
@@ -360,12 +386,25 @@
# WEB CONFIGURATION INTERFACE
WAMP_SECRET_URL = "secret"
-webExposedConfigItems = ['active', 'url', 'ID']
+webExposedConfigItems = [
+ 'active', 'url', 'ID',
+ "clientFactoryOptions.maxDelay",
+ "protocolOptions.autoPingInterval",
+ "protocolOptions.autoPingTimeout"
+]
def wampConfigDefault(ctx, argument):
if lastKnownConfig is not None:
- return lastKnownConfig.get(argument.name, None)
+ # Check if name is composed with an intermediate dot symbol and go deep in lastKnownConfig if it is
+ argument_name_path = argument.name.split(".")
+ searchValue = lastKnownConfig
+ while argument_name_path:
+ if searchValue:
+ searchValue = searchValue.get(argument_name_path.pop(0), None)
+ else:
+ break
+ return searchValue
def wampConfig(**kwargs):
@@ -378,9 +417,16 @@
newConfig = lastKnownConfig.copy()
for argname in webExposedConfigItems:
+ # Check if name is composed with an intermediate dot symbol and go deep in lastKnownConfig if it is
+ # and then set a new value.
+ argname_path = argname.split(".")
+ arg_last = argname_path.pop()
arg = kwargs.get(argname, None)
if arg is not None:
- newConfig[argname] = arg
+ tmpConf = newConfig
+ while argname_path:
+ tmpConf = tmpConf.setdefault(argname_path.pop(0), {})
+ tmpConf[arg_last] = arg
SetConfiguration(newConfig)
@@ -427,8 +473,17 @@
default=wampConfigDefault)),
("url",
annotate.String(label=_("WAMP Server URL"),
- default=wampConfigDefault))]
-
+ default=wampConfigDefault)),
+ ("clientFactoryOptions.maxDelay",
+ annotate.Integer(label=_("Max reconnection delay (s)"),
+ default=wampConfigDefault)),
+ ("protocolOptions.autoPingInterval",
+ annotate.Integer(label=_("Auto ping interval (s)"),
+ default=wampConfigDefault)),
+ ("protocolOptions.autoPingTimeout",
+ annotate.Integer(label=_("Auto ping timeout (s)"),
+ default=wampConfigDefault))
+ ]
def deliverWampSecret(ctx, segments):
# filename = segments[1].decode('utf-8')
--- a/svghmi/svghmi.py Tue Oct 19 13:09:45 2021 +0200
+++ b/svghmi/svghmi.py Wed Oct 20 08:57:07 2021 +0200
@@ -56,6 +56,8 @@
def Generate_C(self, buildpath, varlist, IECCFLAGS):
global hmi_tree_root, on_hmitree_update, maxConnectionsTotal
+ maxConnectionsTotal = 0
+
already_found_watchdog = False
found_SVGHMI_instance = False
for CTNChild in self.GetCTR().IterChildren():
--- a/targets/Linux/plc_Linux_main.c Tue Oct 19 13:09:45 2021 +0200
+++ b/targets/Linux/plc_Linux_main.c Wed Oct 20 08:57:07 2021 +0200
@@ -217,7 +217,7 @@
/* Called by PLC thread on each new python command*/
void UnBlockPythonCommands(void)
{
- /* signal debugger thread it can read data */
+ /* signal python thread it can read data */
pthread_mutex_unlock(&python_wait_mutex);
}