--- a/runtime/Modbus_config.py Fri Jun 05 18:02:12 2020 +0100
+++ b/runtime/Modbus_config.py Sat Jun 06 07:24:42 2020 +0100
@@ -74,6 +74,59 @@
+class MB_StopBits(annotate.Choice): + def coerce(self, val, configurable): + def __init__(self, *args, **kwargs): + annotate.Choice.__init__(self, choices = self._choices, *args, **kwargs) +class MB_Baud(annotate.Choice): + _choices = [110, 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200] + def coerce(self, val, configurable): + def __init__(self, *args, **kwargs): + annotate.Choice.__init__(self, choices = self._choices, *args, **kwargs) +class MB_Parity(annotate.Choice): + # Warning: do _not_ name this variable choice[] without underscore, as that name is + # already used for another similar variable by the underlying class annotate.Choice + _label = ["none", "odd", "even"] + def choice_to_label(self, key): + #_plcobj.LogMessage("Modbus web server extension::choice_to_label() " + str(key)) + return self._label[key] + def coerce(self, val, configurable): + """Coerce a value with the help of an object, which is the object + # Basically, make sure the value the user introduced is valid, and transform + # into something that is valid if necessary or mark it as an error + # (by raising an exception ??). + # We are simply using this functions to transform the input value (a string) + # into an integer. Note that although the available options are all + # integers (0, 1 or 2), even though what is shown on the user interface + # are actually strings, i.e. the labels), these parameters are for some + # reason being parsed as strings, so we need to map them back to an + #_plcobj.LogMessage("Modbus web server extension::coerce " + val ) + def __init__(self, *args, **kwargs): + annotate.Choice.__init__(self, + choices = self._choices, + stringify = self.choice_to_label, # Parameters we will need to get from the C code, but that will not be shown
# on the web interface. Common to all modbus entry types (client/server, tcp/rtu/ascii)
@@ -101,10 +154,10 @@
# (C code var name) (used on web interface) (C data type) (web data type)
- ("device" , _("Serial Port") , ctypes.c_char_p, annotate.String),
- ("baud" , _("Baud Rate") , ctypes.c_int, annotate.Integer),
- ("parity" , _("Parity") , ctypes.c_int, annotate.Integer),
- ("stop_bits" , _("Stop Bits") , ctypes.c_int, annotate.Integer),
+ ("device" , _("Serial Port") , ctypes.c_char_p, annotate.String ), + ("baud" , _("Baud Rate") , ctypes.c_int, MB_Baud ), + ("parity" , _("Parity") , ctypes.c_int, MB_Parity ), + ("stop_bits" , _("Stop Bits") , ctypes.c_int, MB_StopBits ), ("comm_period" , _("Invocation Rate (ms)") , ctypes.c_ulonglong, annotate.Integer)
@@ -123,14 +176,16 @@
# (C code var name) (used on web interface) (C data type) (web data type)
- ("device" , _("Serial Port") , ctypes.c_char_p, annotate.String),
- ("baud" , _("Baud Rate") , ctypes.c_int, annotate.Integer),
- ("parity" , _("Parity") , ctypes.c_int, annotate.Integer),
- ("stop_bits" , _("Stop Bits") , ctypes.c_int, annotate.Integer),
+ ("device" , _("Serial Port") , ctypes.c_char_p, annotate.String ), + ("baud" , _("Baud Rate") , ctypes.c_int, MB_Baud ), + ("parity" , _("Parity") , ctypes.c_int, MB_Parity ), + ("stop_bits" , _("Stop Bits") , ctypes.c_int, MB_StopBits ), ("slave_id" , _("Slave ID") , ctypes.c_ulonglong, annotate.Integer)
# Dictionary containing List of Web viewable parameters
# Note: the dictionary key must be the same as the string returned by the
# __modbus_get_ClientNode_addr_type()
@@ -151,6 +206,10 @@
WebParamListDictDict['server'] = _server_WebParamListDict
#def _CheckPortnumber(port_number):
# """ check validity of the port number """
@@ -496,8 +555,17 @@
# Define the format for the web form used to show/change the current parameters
# We first declare a dynamic function to work as callback to obtain the default values for each parameter
+ # Note: We transform every parameter into a string + # This is not strictly required for parameters of type annotate.Integer that will correctly + # accept the default value as an Integer python object + # This is obviously also not required for parameters of type annotate.String, that are + # always handled as strings. + # However, the annotate.Choice parameters (and all parameters that derive from it, + # sucn as Parity, Baud, etc.) require the default value as a string + # even though we store it as an integer, which is the data type expected + # by the set_***() C functions in mb_runtime.c def __GetWebviewConfigurationValue(ctx, argument):
- return _GetWebviewConfigurationValue(ctx, WebNode_id, argument)
+ return str(_GetWebviewConfigurationValue(ctx, WebNode_id, argument)) webFormInterface = [(name, web_dtype (label=web_label, default=__GetWebviewConfigurationValue))
for name, web_label, c_dtype, web_dtype in WebNode_entry["WebParamList"]]