# HG changeset patch # User Edouard Tisserant # Date 1517408730 -3600 # Node ID e7b6478b4ebcf077d2d905a93df103620ec0d584 # Parent d51d1471939271c1f284c2a012f75819971bfd47 PEP8 conformity for modbus. Most of it done by autopep8, plus some easy refactoring. diff -r d51d14719392 -r e7b6478b4ebc modbus/__init__.py --- a/modbus/__init__.py Wed Jan 31 15:22:43 2018 +0100 +++ b/modbus/__init__.py Wed Jan 31 15:25:30 2018 +0100 @@ -18,7 +18,7 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# +# # This code is made available on the understanding that it will not be # used in safety-critical situations without a full and competent review. diff -r d51d14719392 -r e7b6478b4ebc modbus/mb_utils.py --- a/modbus/mb_utils.py Wed Jan 31 15:22:43 2018 +0100 +++ b/modbus/mb_utils.py Wed Jan 31 15:25:30 2018 +0100 @@ -18,26 +18,34 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# +# # This code is made available on the understanding that it will not be # used in safety-critical situations without a full and competent review. - - -#dictionary implementing: -#key - string with the description we want in the request plugin GUI -#tuple - (modbus function number, request type, max count value, data_type, bit_size) -modbus_function_dict = {"01 - Read Coils" : ( '1', 'req_input', 2000, "BOOL", 1 , "Q", "X", "Coil"), - "02 - Read Input Discretes" : ( '2', 'req_input', 2000, "BOOL", 1 , "I", "X", "Input Discrete"), - "03 - Read Holding Registers" : ( '3', 'req_input', 125, "WORD", 16, "Q", "W", "Holding Register"), - "04 - Read Input Registers" : ( '4', 'req_input', 125, "WORD", 16, "I", "W", "Input Register"), - "05 - Write Single coil" : ( '5','req_output', 1, "BOOL", 1 , "Q", "X", "Coil"), - "06 - Write Single Register" : ( '6','req_output', 1, "WORD", 16, "Q", "W", "Holding Register"), - "15 - Write Multiple Coils" : ('15','req_output', 1968, "BOOL", 1 , "Q", "X", "Coil"), - "16 - Write Multiple Registers" : ('16','req_output', 123, "WORD", 16, "Q", "W", "Holding Register"), - } - +# dictionary implementing: +# key - string with the description we want in the request plugin GUI +# tuple - (modbus function number, request type, max count value, +# data_type, bit_size) +modbus_function_dict = { + "01 - Read Coils": ('1', 'req_input', 2000, "BOOL", 1, "Q", "X", "Coil"), + "02 - Read Input Discretes": ('2', 'req_input', 2000, "BOOL", 1, "I", "X", "Input Discrete"), + "03 - Read Holding Registers": ('3', 'req_input', 125, "WORD", 16, "Q", "W", "Holding Register"), + "04 - Read Input Registers": ('4', 'req_input', 125, "WORD", 16, "I", "W", "Input Register"), + "05 - Write Single coil": ('5', 'req_output', 1, "BOOL", 1, "Q", "X", "Coil"), + "06 - Write Single Register": ('6', 'req_output', 1, "WORD", 16, "Q", "W", "Holding Register"), + "15 - Write Multiple Coils": ('15', 'req_output', 1968, "BOOL", 1, "Q", "X", "Coil"), + "16 - Write Multiple Registers": ('16', 'req_output', 123, "WORD", 16, "Q", "W", "Holding Register")} + + +# Configuration tree value acces helper +def GetCTVal(child, index): + return child.GetParamsAttributes()[0]["children"][index]["value"] + + +# Configuration tree value acces helper, for multiple values +def GetCTVals(child, indexes): + return map(lambda index: GetCTVal(child, index), indexes) def GetTCPServerNodePrinted(self, child): @@ -49,26 +57,22 @@ {"%(locnodestr)s", %(slaveid)s, {naf_tcp, {.tcp = {%(host)s, "%(port)s", DEF_CLOSE_ON_SILENCE}}}, -1 /* mb_nd */, 0 /* init_state */}''' location = ".".join(map(str, child.GetCurrentLocation())) - host = child.GetParamsAttributes()[0]["children"][0]["value"] - port = child.GetParamsAttributes()[0]["children"][1]["value"] - slaveid = child.GetParamsAttributes()[0]["children"][2]["value"] - if host=="#ANY#": - host='INADDR_ANY' + host, port, slaveid = GetCTVals(child, range(3)) + if host == "#ANY#": + host = 'INADDR_ANY' else: - host='"'+host+'"' - #slaveid = child.GetParamsAttributes()[0]["children"][2]["value"] - #if int(slaveid) not in xrange(256): - #self.GetCTRoot().logger.write_error("Error: Wrong slave ID in %s server node\nModbus Plugin C code returns empty\n"%location) - #return None - - node_dict = {"locnodestr" : location, - "host" : host, - "port" : port, - "slaveid" : slaveid, - } - return node_init_template % node_dict - - + host = '"' + host + '"' + # slaveid = GetCTVal(child, 2) + # if int(slaveid) not in xrange(256): + # self.GetCTRoot().logger.write_error("Error: Wrong slave ID in %s server node\nModbus Plugin C code returns empty\n"%location) + # return None + + node_dict = {"locnodestr": location, + "host": host, + "port": port, + "slaveid": slaveid, + } + return node_init_template % node_dict def GetTCPServerMemAreaPrinted(self, child, nodeid): @@ -84,27 +88,28 @@ request_dict["locreqstr"] = "_".join(map(str, child.GetCurrentLocation())) request_dict["nodeid"] = str(nodeid) - request_dict["address"] = child.GetParamsAttributes()[0]["children"][2]["value"] + request_dict["address"] = GetCTVal(child, 2) if int(request_dict["address"]) not in xrange(65536): - self.GetCTRoot().logger.write_error("Modbus plugin: Invalid Start Address in server memory area node %(locreqstr)s (Must be in the range [0..65535])\nModbus plugin: Aborting C code generation for this node\n"%request_dict) - return None - request_dict["count"] = child.GetParamsAttributes()[0]["children"][1]["value"] + self.GetCTRoot().logger.write_error( + "Modbus plugin: Invalid Start Address in server memory area node %(locreqstr)s (Must be in the range [0..65535])\nModbus plugin: Aborting C code generation for this node\n" % request_dict) + return None + request_dict["count"] = GetCTVal(child, 1) if int(request_dict["count"]) not in xrange(1, 65536): - self.GetCTRoot().logger.write_error("Modbus plugin: Invalid number of channels in server memory area node %(locreqstr)s (Must be in the range [1..65536-start_address])\nModbus plugin: Aborting C code generation for this node\n"%request_dict) - return None - if (int(request_dict["address"]) + int(request_dict["count"])) not in xrange(1,65537): - self.GetCTRoot().logger.write_error("Modbus plugin: Invalid number of channels in server memory area node %(locreqstr)s (Must be in the range [1..65536-start_address])\nModbus plugin: Aborting C code generation for this node\n"%request_dict) - return None - + self.GetCTRoot().logger.write_error( + "Modbus plugin: Invalid number of channels in server memory area node %(locreqstr)s (Must be in the range [1..65536-start_address])\nModbus plugin: Aborting C code generation for this node\n" % request_dict) + return None + if (int(request_dict["address"]) + int(request_dict["count"])) not in xrange(1, 65537): + self.GetCTRoot().logger.write_error( + "Modbus plugin: Invalid number of channels in server memory area node %(locreqstr)s (Must be in the range [1..65536-start_address])\nModbus plugin: Aborting C code generation for this node\n" % request_dict) + return None + return "" - - -modbus_serial_baudrate_list = ["110", "300", "600", "1200", "2400", "4800", "9600", "19200", "38400", "57600", "115200"] +modbus_serial_baudrate_list = [ + "110", "300", "600", "1200", "2400", "4800", "9600", "19200", "38400", "57600", "115200"] modbus_serial_stopbits_list = ["1", "2"] -modbus_serial_parity_dict = {"none": 0, "odd": 1, "even": 2} - +modbus_serial_parity_dict = {"none": 0, "odd": 1, "even": 2} def GetRTUSlaveNodePrinted(self, child): @@ -116,24 +121,17 @@ {"%(locnodestr)s", %(slaveid)s, {naf_rtu, {.rtu = {"%(device)s", %(baud)s /*baud*/, %(parity)s /*parity*/, 8 /*data bits*/, %(stopbits)s, 0 /* ignore echo */}}}, -1 /* mb_nd */, 0 /* init_state */}''' location = ".".join(map(str, child.GetCurrentLocation())) - device = child.GetParamsAttributes()[0]["children"][0]["value"] - baud = child.GetParamsAttributes()[0]["children"][1]["value"] - parity = child.GetParamsAttributes()[0]["children"][2]["value"] - stopbits = child.GetParamsAttributes()[0]["children"][3]["value"] - slaveid = child.GetParamsAttributes()[0]["children"][4]["value"] - - node_dict = {"locnodestr" : location, - "device" : device, - "baud" : baud, - "parity" : modbus_serial_parity_dict[parity], - "stopbits" : stopbits, - "slaveid" : slaveid - } - return node_init_template % node_dict - - - - + device, baud, parity, stopbits, slaveid = GetCTVals(child, range(5)) + + node_dict = {"locnodestr": location, + "device": device, + "baud": baud, + "parity": modbus_serial_parity_dict[parity], + "stopbits": stopbits, + "slaveid": slaveid + } + return node_init_template % node_dict + def GetRTUClientNodePrinted(self, child): """ @@ -143,23 +141,17 @@ node_init_template = '''/*node %(locnodestr)s*/ {"%(locnodestr)s", {naf_rtu, {.rtu = {"%(device)s", %(baud)s /*baud*/, %(parity)s /*parity*/, 8 /*data bits*/, %(stopbits)s, 0 /* ignore echo */}}}, -1 /* mb_nd */, 0 /* init_state */, %(coms_period)s /* communication period */}''' - location = ".".join(map(str, child.GetCurrentLocation())) - device = child.GetParamsAttributes()[0]["children"][0]["value"] - baud = child.GetParamsAttributes()[0]["children"][1]["value"] - parity = child.GetParamsAttributes()[0]["children"][2]["value"] - stopbits = child.GetParamsAttributes()[0]["children"][3]["value"] - coms_period = child.GetParamsAttributes()[0]["children"][4]["value"] - - node_dict = {"locnodestr" : location, - "device" : device, - "baud" : baud, - "parity" : modbus_serial_parity_dict[parity], - "stopbits" : stopbits, - "coms_period" : coms_period - } - return node_init_template % node_dict - - + location = ".".join(map(str, child.GetCurrentLocation())) + device, baud, parity, stopbits, coms_period = GetCTVals(child, range(5)) + + node_dict = {"locnodestr": location, + "device": device, + "baud": baud, + "parity": modbus_serial_parity_dict[parity], + "stopbits": stopbits, + "coms_period": coms_period + } + return node_init_template % node_dict def GetTCPClientNodePrinted(self, child): @@ -171,18 +163,14 @@ {"%(locnodestr)s", {naf_tcp, {.tcp = {"%(host)s", "%(port)s", DEF_CLOSE_ON_SILENCE}}}, -1 /* mb_nd */, 0 /* init_state */, %(coms_period)s /* communication period */, 0 /* prev_error */}''' location = ".".join(map(str, child.GetCurrentLocation())) - host = child.GetParamsAttributes()[0]["children"][0]["value"] - port = child.GetParamsAttributes()[0]["children"][1]["value"] - coms_period = child.GetParamsAttributes()[0]["children"][2]["value"] - - node_dict = {"locnodestr" : location, - "host" : host, - "port" : port, - "coms_period" : coms_period - } - return node_init_template % node_dict - - + host, port, coms_period = GetCTVals(child, range(3)) + + node_dict = {"locnodestr": location, + "host": host, + "port": port, + "coms_period": coms_period + } + return node_init_template % node_dict def GetClientRequestPrinted(self, child, nodeid): @@ -199,38 +187,41 @@ {"%(locreqstr)s", %(nodeid)s, %(slaveid)s, %(iotype)s, %(func_nr)s, %(address)s , %(count)s, DEF_REQ_SEND_RETRIES, 0 /* error_code */, 0 /* prev_code */, {%(timeout_s)d, %(timeout_ns)d} /* timeout */, {%(buffer)s}, {%(buffer)s}}''' - - timeout = int(child.GetParamsAttributes()[0]["children"][4]["value"]) - timeout_s = int(timeout / 1000) - timeout_ms = timeout - (timeout_s * 1000) - timeout_ns = timeout_ms * 1000000 - - request_dict = {} - - request_dict["locreqstr" ] = "_".join(map(str, child.GetCurrentLocation())) - request_dict["nodeid" ] = str(nodeid) - request_dict["slaveid" ] = child.GetParamsAttributes()[0]["children"][1]["value"] - request_dict["address" ] = child.GetParamsAttributes()[0]["children"][3]["value"] - request_dict["count" ] = child.GetParamsAttributes()[0]["children"][2]["value"] - request_dict["timeout" ] = timeout - request_dict["timeout_s" ] = timeout_s - request_dict["timeout_ns"] = timeout_ns - request_dict["buffer" ] = ",".join(['0'] * int(child.GetParamsAttributes()[0]["children"][2]["value"])) - request_dict["func_nr" ] = modbus_function_dict[child.GetParamsAttributes()[0]["children"][0]["value"]][0] - request_dict["iotype" ] = modbus_function_dict[child.GetParamsAttributes()[0]["children"][0]["value"]][1] - request_dict["maxcount" ] = modbus_function_dict[child.GetParamsAttributes()[0]["children"][0]["value"]][2] - + + timeout = int(GetCTVal(child, 4)) + timeout_s = int(timeout / 1000) + timeout_ms = timeout - (timeout_s * 1000) + timeout_ns = timeout_ms * 1000000 + + request_dict = { + "locreqstr": "_".join(map(str, child.GetCurrentLocation())), + "nodeid": str(nodeid), + "slaveid": GetCTVal(child, 1), + "address": GetCTVal(child, 3), + "count": GetCTVal(child, 2), + "timeout": timeout, + "timeout_s": timeout_s, + "timeout_ns": timeout_ns, + "buffer": ",".join(['0'] * int(GetCTVal(child, 2))), + "func_nr": modbus_function_dict[GetCTVal(child, 0)][0], + "iotype": modbus_function_dict[GetCTVal(child, 0)][1], + "maxcount": modbus_function_dict[GetCTVal(child, 0)][2]} + if int(request_dict["slaveid"]) not in xrange(256): - self.GetCTRoot().logger.write_error("Modbus plugin: Invalid slaveID in TCP client request node %(locreqstr)s (Must be in the range [0..255])\nModbus plugin: Aborting C code generation for this node\n"%request_dict) + self.GetCTRoot().logger.write_error( + "Modbus plugin: Invalid slaveID in TCP client request node %(locreqstr)s (Must be in the range [0..255])\nModbus plugin: Aborting C code generation for this node\n" % request_dict) return None if int(request_dict["address"]) not in xrange(65536): - self.GetCTRoot().logger.write_error("Modbus plugin: Invalid Start Address in TCP client request node %(locreqstr)s (Must be in the range [0..65535])\nModbus plugin: Aborting C code generation for this node\n"%request_dict) - return None - if int(request_dict["count"]) not in xrange(1, 1+int(request_dict["maxcount"])): - self.GetCTRoot().logger.write_error("Modbus plugin: Invalid number of channels in TCP client request node %(locreqstr)s (Must be in the range [1..%(maxcount)s])\nModbus plugin: Aborting C code generation for this node\n"%request_dict) - return None - if (int(request_dict["address"]) + int(request_dict["count"])) not in xrange(1,65537): - self.GetCTRoot().logger.write_error("Modbus plugin: Invalid number of channels in TCP client request node %(locreqstr)s (start_address + nr_channels must be less than 65536)\nModbus plugin: Aborting C code generation for this node\n"%request_dict) - return None - + self.GetCTRoot().logger.write_error( + "Modbus plugin: Invalid Start Address in TCP client request node %(locreqstr)s (Must be in the range [0..65535])\nModbus plugin: Aborting C code generation for this node\n" % request_dict) + return None + if int(request_dict["count"]) not in xrange(1, 1 + int(request_dict["maxcount"])): + self.GetCTRoot().logger.write_error( + "Modbus plugin: Invalid number of channels in TCP client request node %(locreqstr)s (Must be in the range [1..%(maxcount)s])\nModbus plugin: Aborting C code generation for this node\n" % request_dict) + return None + if (int(request_dict["address"]) + int(request_dict["count"])) not in xrange(1, 65537): + self.GetCTRoot().logger.write_error( + "Modbus plugin: Invalid number of channels in TCP client request node %(locreqstr)s (start_address + nr_channels must be less than 65536)\nModbus plugin: Aborting C code generation for this node\n" % request_dict) + return None + return req_init_template % request_dict diff -r d51d14719392 -r e7b6478b4ebc modbus/modbus.py --- a/modbus/modbus.py Wed Jan 31 15:22:43 2018 +0100 +++ b/modbus/modbus.py Wed Jan 31 15:25:30 2018 +0100 @@ -18,33 +18,31 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# +# # This code is made available on the understanding that it will not be # used in safety-critical situations without a full and competent review. - - -import os, sys -base_folder = os.path.split(os.path.dirname(os.path.realpath(__file__)))[0] -base_folder = os.path.join(base_folder, "..") -ModbusPath = os.path.join(base_folder, "Modbus") - +import os +import sys from mb_utils import * import wx from ConfigTreeNode import ConfigTreeNode from PLCControler import LOCATION_CONFNODE, LOCATION_MODULE, LOCATION_GROUP, LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY - - -################################################### -################################################### -# # -# C L I E N T R E Q U E S T # -# # -################################################### -################################################### +base_folder = os.path.split(os.path.dirname(os.path.realpath(__file__)))[0] +base_folder = os.path.join(base_folder, "..") +ModbusPath = os.path.join(base_folder, "Modbus") + + +# +# +# +# C L I E N T R E Q U E S T # +# +# +# class _RequestPlug: @@ -90,8 +88,8 @@ """ - def GetParamsAttributes(self, path = None): - infos = ConfigTreeNode.GetParamsAttributes(self, path = path) + def GetParamsAttributes(self, path=None): + infos = ConfigTreeNode.GetParamsAttributes(self, path=path) for element in infos: if element["name"] == "ModbusRequest": for child in element["children"]: @@ -100,25 +98,25 @@ list.sort() child["type"] = list return infos - + def GetVariableLocationTree(self): current_location = self.GetCurrentLocation() name = self.BaseParams.getName() address = self.GetParamsAttributes()[0]["children"][3]["value"] - count = self.GetParamsAttributes()[0]["children"][2]["value"] - function= self.GetParamsAttributes()[0]["children"][0]["value"] + count = self.GetParamsAttributes()[0]["children"][2]["value"] + function = self.GetParamsAttributes()[0]["children"][0]["value"] # 'BOOL' or 'WORD' - datatype= modbus_function_dict[function][3] + datatype = modbus_function_dict[function][3] # 1 or 16 - datasize= modbus_function_dict[function][4] + datasize = modbus_function_dict[function][4] # 'Q' for coils and holding registers, 'I' for input discretes and input registers - datazone= modbus_function_dict[function][5] + datazone = modbus_function_dict[function][5] # 'X' for bits, 'W' for words - datatacc= modbus_function_dict[function][6] + datatacc = modbus_function_dict[function][6] # 'Coil', 'Holding Register', 'Input Discrete' or 'Input Register' - dataname= modbus_function_dict[function][7] + dataname = modbus_function_dict[function][7] entries = [] - for offset in range(address, address+count): + for offset in range(address, address + count): entries.append({ "name": dataname + " " + str(offset), "type": LOCATION_VAR_MEMORY, @@ -128,14 +126,10 @@ "location": datatacc + ".".join([str(i) for i in current_location]) + "." + str(offset), "description": "description", "children": []}) - return {"name": name, - "type": LOCATION_CONFNODE, - "location": ".".join([str(i) for i in current_location]) + ".x", - "children": entries} - - - - + return {"name": name, + "type": LOCATION_CONFNODE, + "location": ".".join([str(i) for i in current_location]) + ".x", + "children": entries} def CTNGenerate_C(self, buildpath, locations): """ @@ -151,24 +145,26 @@ @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND """ return [], "", False - - -################################################### -################################################### -# # -# S E R V E R M E M O R Y A R E A # -# # -################################################### -################################################### - -#dictionary implementing: -#key - string with the description we want in the request plugin GUI -#list - (modbus function number, request type, max count value) -modbus_memtype_dict = {"01 - Coils" : ( '1', 'rw_bits', 65536, "BOOL", 1 , "Q", "X", "Coil"), - "02 - Input Discretes" : ( '2', 'ro_bits', 65536, "BOOL", 1 , "I", "X", "Input Discrete"), - "03 - Holding Registers" :( '3', 'rw_words', 65536, "WORD", 16 , "Q", "W", "Holding Register"), - "04 - Input Registers" : ( '4', 'ro_words', 65536, "WORD", 16 , "I", "W", "Input Register"), - } + + +# +# +# +# S E R V E R M E M O R Y A R E A # +# +# +# + +# dictionary implementing: +# key - string with the description we want in the request plugin GUI +# list - (modbus function number, request type, max count value) +modbus_memtype_dict = { + "01 - Coils": ('1', 'rw_bits', 65536, "BOOL", 1, "Q", "X", "Coil"), + "02 - Input Discretes": ('2', 'ro_bits', 65536, "BOOL", 1, "I", "X", "Input Discrete"), + "03 - Holding Registers": ('3', 'rw_words', 65536, "WORD", 16, "Q", "W", "Holding Register"), + "04 - Input Registers": ('4', 'ro_words', 65536, "WORD", 16, "I", "W", "Input Register"), +} + class _MemoryAreaPlug: XSD = """ @@ -197,8 +193,8 @@ """ - def GetParamsAttributes(self, path = None): - infos = ConfigTreeNode.GetParamsAttributes(self, path = path) + def GetParamsAttributes(self, path=None): + infos = ConfigTreeNode.GetParamsAttributes(self, path=path) for element in infos: if element["name"] == "MemoryArea": for child in element["children"]: @@ -212,20 +208,20 @@ current_location = self.GetCurrentLocation() name = self.BaseParams.getName() address = self.GetParamsAttributes()[0]["children"][2]["value"] - count = self.GetParamsAttributes()[0]["children"][1]["value"] - function= self.GetParamsAttributes()[0]["children"][0]["value"] + count = self.GetParamsAttributes()[0]["children"][1]["value"] + function = self.GetParamsAttributes()[0]["children"][0]["value"] # 'BOOL' or 'WORD' - datatype= modbus_memtype_dict[function][3] + datatype = modbus_memtype_dict[function][3] # 1 or 16 - datasize= modbus_memtype_dict[function][4] + datasize = modbus_memtype_dict[function][4] # 'Q' for coils and holding registers, 'I' for input discretes and input registers - datazone= modbus_memtype_dict[function][5] + datazone = modbus_memtype_dict[function][5] # 'X' for bits, 'W' for words - datatacc= modbus_memtype_dict[function][6] + datatacc = modbus_memtype_dict[function][6] # 'Coil', 'Holding Register', 'Input Discrete' or 'Input Register' - dataname= modbus_memtype_dict[function][7] + dataname = modbus_memtype_dict[function][7] entries = [] - for offset in range(address, address+count): + for offset in range(address, address + count): entries.append({ "name": dataname + " " + str(offset), "type": LOCATION_VAR_MEMORY, @@ -235,10 +231,10 @@ "location": datatacc + ".".join([str(i) for i in current_location]) + "." + str(offset), "description": "description", "children": []}) - return {"name": name, - "type": LOCATION_CONFNODE, - "location": ".".join([str(i) for i in current_location]) + ".x", - "children": entries} + return {"name": name, + "type": LOCATION_CONFNODE, + "location": ".".join([str(i) for i in current_location]) + ".x", + "children": entries} def CTNGenerate_C(self, buildpath, locations): """ @@ -255,14 +251,14 @@ """ return [], "", False - -################################################### -################################################### -# # -# T C P C L I E N T # -# # -################################################### -################################################### + +# +# +# +# T C P C L I E N T # +# +# +# class _ModbusTCPclientPlug: XSD = """ @@ -283,8 +279,9 @@ """ - # NOTE: Max value of 2147483647 (i32_max) for Invocation_Rate_in_ms corresponds to aprox 25 days. - CTNChildrenTypes = [("ModbusRequest",_RequestPlug, "Request")] + # NOTE: Max value of 2147483647 (i32_max) for Invocation_Rate_in_ms + # corresponds to aprox 25 days. + CTNChildrenTypes = [("ModbusRequest", _RequestPlug, "Request")] # TODO: Replace with CTNType !!! PlugType = "ModbusTCPclient" @@ -309,19 +306,17 @@ return [], "", False - - -################################################### -################################################### -# # -# T C P S E R V E R # -# # -################################################### -################################################### +# +# +# +# T C P S E R V E R # +# +# +# class _ModbusTCPserverPlug: # NOTE: the Port number is a 'string' and not an 'integer'! - # This is because the underlying modbus library accepts strings + # This is because the underlying modbus library accepts strings # (e.g.: well known port names!) XSD = """ @@ -341,7 +336,7 @@ """ - CTNChildrenTypes = [("MemoryArea",_MemoryAreaPlug, "Memory Area")] + CTNChildrenTypes = [("MemoryArea", _MemoryAreaPlug, "Memory Area")] # TODO: Replace with CTNType !!! PlugType = "ModbusTCPserver" @@ -355,7 +350,7 @@ # port number: IP port used by this Modbus/IP server def GetIPServerPortNumbers(self): port = self.GetParamsAttributes()[0]["children"][1]["value"] - return [(self.GetCurrentLocation() , port)] + return [(self.GetCurrentLocation(), port)] def CTNGenerate_C(self, buildpath, locations): """ @@ -373,15 +368,13 @@ return [], "", False - - -################################################### -################################################### -# # -# R T U C L I E N T # -# # -################################################### -################################################### +# +# +# +# R T U C L I E N T # +# +# +# class _ModbusRTUclientPlug: XSD = """ @@ -404,13 +397,14 @@ """ - # NOTE: Max value of 2147483647 (i32_max) for Invocation_Rate_in_ms corresponds to aprox 25 days. - CTNChildrenTypes = [("ModbusRequest",_RequestPlug, "Request")] + # NOTE: Max value of 2147483647 (i32_max) for Invocation_Rate_in_ms + # corresponds to aprox 25 days. + CTNChildrenTypes = [("ModbusRequest", _RequestPlug, "Request")] # TODO: Replace with CTNType !!! PlugType = "ModbusRTUclient" - def GetParamsAttributes(self, path = None): - infos = ConfigTreeNode.GetParamsAttributes(self, path = path) + def GetParamsAttributes(self, path=None): + infos = ConfigTreeNode.GetParamsAttributes(self, path=path) for element in infos: if element["name"] == "ModbusRTUclient": for child in element["children"]: @@ -421,7 +415,7 @@ if child["name"] == "Parity": child["type"] = modbus_serial_parity_dict.keys() return infos - + # Return the number of (modbus library) nodes this specific RTU client will need # return type: (tcp nodes, rtu nodes, ascii nodes) def GetNodeCount(self): @@ -443,14 +437,13 @@ return [], "", False - -################################################### -################################################### -# # -# R T U S L A V E # -# # -################################################### -################################################### +# +# +# +# R T U S L A V E # +# +# +# class _ModbusRTUslavePlug: @@ -474,12 +467,12 @@ """ - CTNChildrenTypes = [("MemoryArea",_MemoryAreaPlug, "Memory Area")] + CTNChildrenTypes = [("MemoryArea", _MemoryAreaPlug, "Memory Area")] # TODO: Replace with CTNType !!! PlugType = "ModbusRTUslave" - def GetParamsAttributes(self, path = None): - infos = ConfigTreeNode.GetParamsAttributes(self, path = path) + def GetParamsAttributes(self, path=None): + infos = ConfigTreeNode.GetParamsAttributes(self, path=path) for element in infos: if element["name"] == "ModbusRTUslave": for child in element["children"]: @@ -490,7 +483,7 @@ if child["name"] == "Parity": child["type"] = modbus_serial_parity_dict.keys() return infos - + # Return the number of (modbus library) nodes this specific RTU slave will need # return type: (tcp nodes, rtu nodes, ascii nodes) def GetNodeCount(self): @@ -511,15 +504,18 @@ """ return [], "", False - - -################################################### -################################################### -# # -# R O O T C L A S S # -# # -################################################### -################################################### + +def _lt_to_str(loctuple): + return '.'.join(map(str, loctuple)) + + +# +# +# +# R O O T C L A S S # +# +# +# class RootClass: XSD = """ @@ -537,23 +533,23 @@ """ - CTNChildrenTypes = [("ModbusTCPclient",_ModbusTCPclientPlug, "Modbus TCP Client") - ,("ModbusTCPserver",_ModbusTCPserverPlug, "Modbus TCP Server") - ,("ModbusRTUclient",_ModbusRTUclientPlug, "Modbus RTU Client") - ,("ModbusRTUslave", _ModbusRTUslavePlug, "Modbus RTU Slave") - ] - + CTNChildrenTypes = [("ModbusTCPclient", _ModbusTCPclientPlug, "Modbus TCP Client"), ("ModbusTCPserver", _ModbusTCPserverPlug, "Modbus TCP Server"), ("ModbusRTUclient", _ModbusRTUclientPlug, "Modbus RTU Client"), ("ModbusRTUslave", _ModbusRTUslavePlug, "Modbus RTU Slave") + ] + # Return the number of (modbus library) nodes this specific instance of the modbus plugin will need # return type: (tcp nodes, rtu nodes, ascii nodes) def GetNodeCount(self): - max_remote_tcpclient = self.GetParamsAttributes()[0]["children"][0]["value"] + max_remote_tcpclient = self.GetParamsAttributes()[ + 0]["children"][0]["value"] total_node_count = (max_remote_tcpclient, 0, 0) for child in self.IECSortedChildren(): # ask each child how many nodes it needs, and add them all up. - total_node_count = tuple(x1 + x2 for x1, x2 in zip(total_node_count, child.GetNodeCount())) + total_node_count = tuple( + x1 + x2 for x1, x2 in zip(total_node_count, child.GetNodeCount())) return total_node_count - # Return a list with tuples of the (location, port numbers) used by all the Modbus/IP servers + # Return a list with tuples of the (location, port numbers) used by all + # the Modbus/IP servers def GetIPServerPortNumbers(self): IPServer_port_numbers = [] for child in self.IECSortedChildren(): @@ -562,54 +558,64 @@ return IPServer_port_numbers def CTNGenerate_C(self, buildpath, locations): - #print "#############" - #print self.__class__ - #print type(self) - #print "self.CTNType >>>" - #print self.CTNType - #print "type(self.CTNType) >>>" - #print type(self.CTNType) - #print "#############" - - loc_dict = {"locstr" : "_".join(map(str,self.GetCurrentLocation())), - } - + # print "#############" + # print self.__class__ + # print type(self) + # print "self.CTNType >>>" + # print self.CTNType + # print "type(self.CTNType) >>>" + # print type(self.CTNType) + # print "#############" + + loc_dict = {"locstr": "_".join(map(str, self.GetCurrentLocation())), + } + # Determine the number of (modbus library) nodes ALL instances of the modbus plugin will need # total_node_count: (tcp nodes, rtu nodes, ascii nodes) # Also get a list with tuples of (location, IP port numbers) used by all the Modbus/IP server nodes # This list is later used to search for duplicates in port numbers! # IPServer_port_numbers = [(location ,IPserver_port_number), ...] # location: tuple similar to (0, 3, 1) representing the location in the configuration tree "0.3.1.x" - # IPserver_port_number: a number (i.e. port number used by the Modbus/IP server) + # IPserver_port_number: a number (i.e. port number used by the + # Modbus/IP server) total_node_count = (0, 0, 0) IPServer_port_numbers = [] for CTNInstance in self.GetCTRoot().IterChildren(): if CTNInstance.CTNType == "modbus": - # ask each modbus plugin instance how many nodes it needs, and add them all up. - total_node_count = tuple(x1 + x2 for x1, x2 in zip(total_node_count, CTNInstance.GetNodeCount())) - IPServer_port_numbers.extend(CTNInstance.GetIPServerPortNumbers()) + # ask each modbus plugin instance how many nodes it needs, and + # add them all up. + total_node_count = tuple(x1 + x2 for x1, x2 in zip( + total_node_count, CTNInstance.GetNodeCount())) + IPServer_port_numbers.extend( + CTNInstance.GetIPServerPortNumbers()) # Search for use of duplicate port numbers by Modbus/IP servers - #print IPServer_port_numbers + # print IPServer_port_numbers # ..but first define a lambda function to convert a tuple with the config tree location to a nice looking string - # for e.g., convert the tuple (0, 3, 4) to "0.3.4" - lt_to_str = lambda loctuple: '.'.join(map(str, loctuple)) - for i in range(0, len(IPServer_port_numbers)-1): - for j in range (i+1, len(IPServer_port_numbers)): + # for e.g., convert the tuple (0, 3, 4) to "0.3.4" + + for i in range(0, len(IPServer_port_numbers) - 1): + for j in range(i + 1, len(IPServer_port_numbers)): if IPServer_port_numbers[i][1] == IPServer_port_numbers[j][1]: - self.GetCTRoot().logger.write_warning(_("Error: Modbus/IP Servers %s.x and %s.x use the same port number %s.\n")%(lt_to_str(IPServer_port_numbers[i][0]), lt_to_str(IPServer_port_numbers[j][0]), IPServer_port_numbers[j][1])) - raise Exception, False - # TODO: return an error code instead of raising an exception - - # Determine the current location in Beremiz's project configuration tree + self.GetCTRoot().logger.write_warning( + _("Error: Modbus/IP Servers %s.x and %s.x use the same port number %s.\n") % ( + _lt_to_str(IPServer_port_numbers[i][0]), + _lt_to_str(IPServer_port_numbers[j][0]), + IPServer_port_numbers[j][1])) + raise Exception + # TODO: return an error code instead of raising an + # exception + + # Determine the current location in Beremiz's project configuration + # tree current_location = self.GetCurrentLocation() - + # define a unique name for the generated C and h files prefix = "_".join(map(str, current_location)) - Gen_MB_c_path = os.path.join(buildpath, "MB_%s.c"%prefix) - Gen_MB_h_path = os.path.join(buildpath, "MB_%s.h"%prefix) - c_filename = os.path.join(os.path.split(__file__)[0],"mb_runtime.c") - h_filename = os.path.join(os.path.split(__file__)[0],"mb_runtime.h") + Gen_MB_c_path = os.path.join(buildpath, "MB_%s.c" % prefix) + Gen_MB_h_path = os.path.join(buildpath, "MB_%s.h" % prefix) + c_filename = os.path.join(os.path.split(__file__)[0], "mb_runtime.c") + h_filename = os.path.join(os.path.split(__file__)[0], "mb_runtime.h") tcpclient_reqs_count = 0 rtuclient_reqs_count = 0 @@ -624,124 +630,134 @@ client_nodeid = 0 client_requestid = 0 server_id = 0 - + server_node_list = [] client_node_list = [] client_request_list = [] server_memarea_list = [] loc_vars = [] - loc_vars_list = [] # list of variables already declared in C code! + loc_vars_list = [] # list of variables already declared in C code! for child in self.IECSortedChildren(): - #print "<<<<<<<<<<<<<" - #print "child (self.IECSortedChildren())----->" - #print child.__class__ - #print ">>>>>>>>>>>>>" - ###################################### + # print "<<<<<<<<<<<<<" + # print "child (self.IECSortedChildren())----->" + # print child.__class__ + # print ">>>>>>>>>>>>>" + # if child.PlugType == "ModbusTCPserver": tcpserver_node_count += 1 new_node = GetTCPServerNodePrinted(self, child) if new_node is None: - return [],"",False + return [], "", False server_node_list.append(new_node) - ############## + # for subchild in child.IECSortedChildren(): - new_memarea = GetTCPServerMemAreaPrinted(self, subchild, nodeid) + new_memarea = GetTCPServerMemAreaPrinted( + self, subchild, nodeid) if new_memarea is None: - return [],"",False + return [], "", False server_memarea_list.append(new_memarea) - function= subchild.GetParamsAttributes()[0]["children"][0]["value"] + function = subchild.GetParamsAttributes()[ + 0]["children"][0]["value"] # 'ro_bits', 'rw_bits', 'ro_words' or 'rw_words' - memarea= modbus_memtype_dict[function][1] + memarea = modbus_memtype_dict[function][1] for iecvar in subchild.GetLocations(): - #print repr(iecvar) + # print repr(iecvar) absloute_address = iecvar["LOC"][3] - start_address = int(subchild.GetParamsAttributes()[0]["children"][2]["value"]) + start_address = int(GetCTVal(child, 2)) relative_addr = absloute_address - start_address - #test if relative address in request specified range - if relative_addr in xrange(int(subchild.GetParamsAttributes()[0]["children"][1]["value"])): + # test if relative address in request specified range + if relative_addr in xrange(int(GetCTVal(child, 1))): if str(iecvar["NAME"]) not in loc_vars_list: - loc_vars.append("u16 *" + str(iecvar["NAME"]) + " = &server_nodes[%d].mem_area.%s[%d];" % (server_id, memarea, absloute_address)) + loc_vars.append("u16 *" + str(iecvar["NAME"]) + " = &server_nodes[%d].mem_area.%s[%d];" % ( + server_id, memarea, absloute_address)) loc_vars_list.append(str(iecvar["NAME"])) server_id += 1 - ###################################### + # if child.PlugType == "ModbusRTUslave": rtuserver_node_count += 1 new_node = GetRTUSlaveNodePrinted(self, child) if new_node is None: - return [],"",False + return [], "", False server_node_list.append(new_node) - ############## + # for subchild in child.IECSortedChildren(): - new_memarea = GetTCPServerMemAreaPrinted(self, subchild, nodeid) + new_memarea = GetTCPServerMemAreaPrinted( + self, subchild, nodeid) if new_memarea is None: - return [],"",False + return [], "", False server_memarea_list.append(new_memarea) - function= subchild.GetParamsAttributes()[0]["children"][0]["value"] + function = subchild.GetParamsAttributes()[ + 0]["children"][0]["value"] # 'ro_bits', 'rw_bits', 'ro_words' or 'rw_words' - memarea= modbus_memtype_dict[function][1] + memarea = modbus_memtype_dict[function][1] for iecvar in subchild.GetLocations(): - #print repr(iecvar) + # print repr(iecvar) absloute_address = iecvar["LOC"][3] - start_address = int(subchild.GetParamsAttributes()[0]["children"][2]["value"]) + start_address = int(GetCTVal(child, 2)) relative_addr = absloute_address - start_address - #test if relative address in request specified range - if relative_addr in xrange(int(subchild.GetParamsAttributes()[0]["children"][1]["value"])): + # test if relative address in request specified range + if relative_addr in xrange(int(GetCTVal(child, 1))): if str(iecvar["NAME"]) not in loc_vars_list: - loc_vars.append("u16 *" + str(iecvar["NAME"]) + " = &server_nodes[%d].mem_area.%s[%d];" % (server_id, memarea, absloute_address)) + loc_vars.append("u16 *" + str(iecvar["NAME"]) + " = &server_nodes[%d].mem_area.%s[%d];" % ( + server_id, memarea, absloute_address)) loc_vars_list.append(str(iecvar["NAME"])) server_id += 1 - ###################################### + # if child.PlugType == "ModbusTCPclient": tcpclient_reqs_count += len(child.IECSortedChildren()) new_node = GetTCPClientNodePrinted(self, child) if new_node is None: - return [],"",False + return [], "", False client_node_list.append(new_node) for subchild in child.IECSortedChildren(): - new_req = GetClientRequestPrinted(self, subchild, client_nodeid) + new_req = GetClientRequestPrinted( + self, subchild, client_nodeid) if new_req is None: - return [],"",False + return [], "", False client_request_list.append(new_req) for iecvar in subchild.GetLocations(): - #absloute address - start address - relative_addr = iecvar["LOC"][3] - int(subchild.GetParamsAttributes()[0]["children"][3]["value"]) - #test if relative address in request specified range - if relative_addr in xrange(int(subchild.GetParamsAttributes()[0]["children"][2]["value"])): + # absloute address - start address + relative_addr = iecvar["LOC"][3] - int(GetCTVal(child, 3)) + # test if relative address in request specified range + if relative_addr in xrange(int(GetCTVal(child, 2))): if str(iecvar["NAME"]) not in loc_vars_list: - loc_vars.append("u16 *" + str(iecvar["NAME"]) + " = &client_requests[%d].plcv_buffer[%d];" % (client_requestid, relative_addr)) + loc_vars.append( + "u16 *" + str(iecvar["NAME"]) + " = &client_requests[%d].plcv_buffer[%d];" % (client_requestid, relative_addr)) loc_vars_list.append(str(iecvar["NAME"])) client_requestid += 1 tcpclient_node_count += 1 client_nodeid += 1 - ###################################### + # if child.PlugType == "ModbusRTUclient": rtuclient_reqs_count += len(child.IECSortedChildren()) new_node = GetRTUClientNodePrinted(self, child) if new_node is None: - return [],"",False + return [], "", False client_node_list.append(new_node) for subchild in child.IECSortedChildren(): - new_req = GetClientRequestPrinted(self, subchild, client_nodeid) + new_req = GetClientRequestPrinted( + self, subchild, client_nodeid) if new_req is None: - return [],"",False + return [], "", False client_request_list.append(new_req) for iecvar in subchild.GetLocations(): - #absloute address - start address - relative_addr = iecvar["LOC"][3] - int(subchild.GetParamsAttributes()[0]["children"][3]["value"]) - #test if relative address in request specified range - if relative_addr in xrange(int(subchild.GetParamsAttributes()[0]["children"][2]["value"])): + # absloute address - start address + relative_addr = iecvar["LOC"][3] - int(GetCTVal(child, 3)) + # test if relative address in request specified range + if relative_addr in xrange(int(GetCTVal(child, 2))): if str(iecvar["NAME"]) not in loc_vars_list: - loc_vars.append("u16 *" + str(iecvar["NAME"]) + " = &client_requests[%d].plcv_buffer[%d];" % (client_requestid, relative_addr)) + loc_vars.append( + "u16 *" + str(iecvar["NAME"]) + " = &client_requests[%d].plcv_buffer[%d];" % (client_requestid, relative_addr)) loc_vars_list.append(str(iecvar["NAME"])) client_requestid += 1 rtuclient_node_count += 1 client_nodeid += 1 nodeid += 1 - - loc_dict["loc_vars"] = "\n".join(loc_vars) - loc_dict["server_nodes_params"] = ",\n\n".join(server_node_list) - loc_dict["client_nodes_params"] = ",\n\n".join(client_node_list) - loc_dict["client_req_params"] = ",\n\n".join(client_request_list) + + loc_dict["loc_vars"] = "\n".join(loc_vars) + loc_dict["server_nodes_params"] = ",\n\n".join(server_node_list) + loc_dict["client_nodes_params"] = ",\n\n".join(client_node_list) + loc_dict["client_req_params"] = ",\n\n".join(client_request_list) loc_dict["tcpclient_reqs_count"] = str(tcpclient_reqs_count) loc_dict["tcpclient_node_count"] = str(tcpclient_node_count) loc_dict["tcpserver_node_count"] = str(tcpserver_node_count) @@ -751,20 +767,21 @@ loc_dict["ascclient_reqs_count"] = str(ascclient_reqs_count) loc_dict["ascclient_node_count"] = str(ascclient_node_count) loc_dict["ascserver_node_count"] = str(ascserver_node_count) - loc_dict["total_tcpnode_count"] = str(total_node_count[0]) - loc_dict["total_rtunode_count"] = str(total_node_count[1]) - loc_dict["total_ascnode_count"] = str(total_node_count[2]) - loc_dict["max_remote_tcpclient"] = int(self.GetParamsAttributes()[0]["children"][0]["value"]) - - #get template file content into a string, format it with dict - #and write it to proper .h file + loc_dict["total_tcpnode_count"] = str(total_node_count[0]) + loc_dict["total_rtunode_count"] = str(total_node_count[1]) + loc_dict["total_ascnode_count"] = str(total_node_count[2]) + loc_dict["max_remote_tcpclient"] = int( + self.GetParamsAttributes()[0]["children"][0]["value"]) + + # get template file content into a string, format it with dict + # and write it to proper .h file mb_main = open(h_filename).read() % loc_dict - f = open(Gen_MB_h_path,'w') + f = open(Gen_MB_h_path, 'w') f.write(mb_main) f.close() - #same thing as above, but now to .c file + # same thing as above, but now to .c file mb_main = open(c_filename).read() % loc_dict - f = open(Gen_MB_c_path,'w') + f = open(Gen_MB_c_path, 'w') f.write(mb_main) f.close() @@ -772,15 +789,16 @@ LDFLAGS.append(" \"-L" + ModbusPath + "\"") LDFLAGS.append(" -lmb ") LDFLAGS.append(" \"-Wl,-rpath," + ModbusPath + "\"") - #LDFLAGS.append("\"" + os.path.join(ModbusPath, "mb_slave_and_master.o") + "\"") - #LDFLAGS.append("\"" + os.path.join(ModbusPath, "mb_slave.o") + "\"") - #LDFLAGS.append("\"" + os.path.join(ModbusPath, "mb_master.o") + "\"") - #LDFLAGS.append("\"" + os.path.join(ModbusPath, "mb_tcp.o") + "\"") - #LDFLAGS.append("\"" + os.path.join(ModbusPath, "mb_rtu.o") + "\"") - #LDFLAGS.append("\"" + os.path.join(ModbusPath, "mb_ascii.o") + "\"") - #LDFLAGS.append("\"" + os.path.join(ModbusPath, "sin_util.o") + "\"") + # LDFLAGS.append("\"" + os.path.join(ModbusPath, "mb_slave_and_master.o") + "\"") + # LDFLAGS.append("\"" + os.path.join(ModbusPath, "mb_slave.o") + "\"") + # LDFLAGS.append("\"" + os.path.join(ModbusPath, "mb_master.o") + "\"") + # LDFLAGS.append("\"" + os.path.join(ModbusPath, "mb_tcp.o") + "\"") + # LDFLAGS.append("\"" + os.path.join(ModbusPath, "mb_rtu.o") + "\"") + # LDFLAGS.append("\"" + os.path.join(ModbusPath, "mb_ascii.o") + "\"") + # LDFLAGS.append("\"" + os.path.join(ModbusPath, "sin_util.o") + "\"") # Target is ARM with linux and not win on x86 so winsock2 (ws2_32) library is useless !!! - #if os.name == 'nt': # other possible values: 'posix' 'os2' 'ce' 'java' 'riscos' - # LDFLAGS.append(" -lws2_32 ") # on windows we need to load winsock library! - - return [(Gen_MB_c_path, ' -I"'+ModbusPath+'"')], LDFLAGS, True + # if os.name == 'nt': # other possible values: 'posix' 'os2' 'ce' 'java' 'riscos' + # LDFLAGS.append(" -lws2_32 ") # on windows we need to load winsock + # library! + + return [(Gen_MB_c_path, ' -I"' + ModbusPath + '"')], LDFLAGS, True