106 ("parity" , _("Parity") , ctypes.c_int, annotate.Integer), |
106 ("parity" , _("Parity") , ctypes.c_int, annotate.Integer), |
107 ("stop_bits" , _("Stop Bits") , ctypes.c_int, annotate.Integer), |
107 ("stop_bits" , _("Stop Bits") , ctypes.c_int, annotate.Integer), |
108 ("comm_period" , _("Invocation Rate (ms)") , ctypes.c_ulonglong, annotate.Integer) |
108 ("comm_period" , _("Invocation Rate (ms)") , ctypes.c_ulonglong, annotate.Integer) |
109 ] |
109 ] |
110 |
110 |
111 |
111 TCPserver_parameters = [ |
|
112 # param. name label ctype type annotate type |
|
113 # (C code var name) (used on web interface) (C data type) (web data type) |
|
114 # (annotate.String, |
|
115 # annotate.Integer, ...) |
|
116 ("host" , _("Local IP Address") , ctypes.c_char_p, annotate.String), |
|
117 ("port" , _("Local Port Number") , ctypes.c_char_p, annotate.String), |
|
118 ("slave_id" , _("Slave ID") , ctypes.c_ubyte, annotate.Integer) |
|
119 ] |
|
120 |
|
121 RTUslave_parameters = [ |
|
122 # param. name label ctype type annotate type |
|
123 # (C code var name) (used on web interface) (C data type) (web data type) |
|
124 # (annotate.String, |
|
125 # annotate.Integer, ...) |
|
126 ("device" , _("Serial Port") , ctypes.c_char_p, annotate.String), |
|
127 ("baud" , _("Baud Rate") , ctypes.c_int, annotate.Integer), |
|
128 ("parity" , _("Parity") , ctypes.c_int, annotate.Integer), |
|
129 ("stop_bits" , _("Stop Bits") , ctypes.c_int, annotate.Integer), |
|
130 ("slave_id" , _("Slave ID") , ctypes.c_ulonglong, annotate.Integer) |
|
131 ] |
|
132 |
|
133 |
|
134 # Dictionary containing List of Web viewable parameters |
112 # Note: the dictionary key must be the same as the string returned by the |
135 # Note: the dictionary key must be the same as the string returned by the |
113 # __modbus_get_ClientNode_addr_type() |
136 # __modbus_get_ClientNode_addr_type() |
114 # __modbus_get_ServerNode_addr_type() |
137 # __modbus_get_ServerNode_addr_type() |
115 # functions implemented in C (see modbus/mb_runtime.c) |
138 # functions implemented in C (see modbus/mb_runtime.c) |
116 _client_parameters = {} |
139 _client_WebParamListDict = {} |
117 _client_parameters["tcp" ] = TCPclient_parameters |
140 _client_WebParamListDict["tcp" ] = TCPclient_parameters |
118 _client_parameters["rtu" ] = RTUclient_parameters |
141 _client_WebParamListDict["rtu" ] = RTUclient_parameters |
119 _client_parameters["ascii"] = [] # (Note: ascii not yet implemented in Beremiz modbus plugin) |
142 _client_WebParamListDict["ascii"] = [] # (Note: ascii not yet implemented in Beremiz modbus plugin) |
|
143 |
|
144 _server_WebParamListDict = {} |
|
145 _server_WebParamListDict["tcp" ] = TCPserver_parameters |
|
146 _server_WebParamListDict["rtu" ] = RTUslave_parameters |
|
147 _server_WebParamListDict["ascii"] = [] # (Note: ascii not yet implemented in Beremiz modbus plugin) |
120 |
148 |
121 |
149 |
122 #def _CheckPortnumber(port_number): |
150 #def _CheckPortnumber(port_number): |
123 # """ check validity of the port number """ |
151 # """ check validity of the port number """ |
124 # try: |
152 # try: |
206 |
234 |
207 return saved_config |
235 return saved_config |
208 |
236 |
209 |
237 |
210 |
238 |
211 def _GetPLCConfiguration(node_id): |
239 def _GetPLCConfiguration(WebNode_id): |
212 """ |
240 """ |
213 Returns a dictionary containing the current Modbus parameter configuration |
241 Returns a dictionary containing the current Modbus parameter configuration |
214 stored in the C variables in the loaded PLC (.so file) |
242 stored in the C variables in the loaded PLC (.so file) |
215 """ |
243 """ |
216 current_config = {} |
244 current_config = {} |
217 addr_type = _TCPclient_list[node_id]["addr_type"] |
245 C_node_id = _WebNodeList[WebNode_id]["C_node_id"] |
218 |
246 WebParamList = _WebNodeList[WebNode_id]["WebParamList"] |
219 for par_name, x1, x2, x3 in _client_parameters[addr_type]: |
247 GetParamFuncs = _WebNodeList[WebNode_id]["GetParamFuncs"] |
220 value = GetParamFuncs[par_name](node_id) |
248 |
|
249 for par_name, x1, x2, x3 in WebParamList: |
|
250 value = GetParamFuncs[par_name](C_node_id) |
221 if value is not None: |
251 if value is not None: |
222 current_config[par_name] = value |
252 current_config[par_name] = value |
223 |
253 |
224 return current_config |
254 return current_config |
225 |
255 |
226 |
256 |
227 |
257 |
228 def _SetPLCConfiguration(node_id, newconfig): |
258 def _SetPLCConfiguration(WebNode_id, newconfig): |
229 """ |
259 """ |
230 Stores the Modbus parameter configuration into the |
260 Stores the Modbus parameter configuration into the |
231 the C variables in the loaded PLC (.so file) |
261 the C variables in the loaded PLC (.so file) |
232 """ |
262 """ |
233 addr_type = _TCPclient_list[node_id]["addr_type"] |
263 C_node_id = _WebNodeList[WebNode_id]["C_node_id"] |
234 |
264 SetParamFuncs = _WebNodeList[WebNode_id]["SetParamFuncs"] |
|
265 |
235 for par_name in newconfig: |
266 for par_name in newconfig: |
236 value = newconfig[par_name] |
267 value = newconfig[par_name] |
237 if value is not None: |
268 if value is not None: |
238 SetParamFuncs[par_name](node_id, value) |
269 SetParamFuncs[par_name](C_node_id, value) |
239 |
270 |
240 |
271 |
241 |
272 |
242 |
273 |
243 def _GetWebviewConfigurationValue(ctx, node_id, argument): |
274 def _GetWebviewConfigurationValue(ctx, WebNode_id, argument): |
244 """ |
275 """ |
245 Callback function, called by the web interface (NevowServer.py) |
276 Callback function, called by the web interface (NevowServer.py) |
246 to fill in the default value of each parameter of the web form |
277 to fill in the default value of each parameter of the web form |
247 |
278 |
248 Note that the real callback function is a dynamically created function that |
279 Note that the real callback function is a dynamically created function that |
249 will simply call this function to do the work. It will also pass the node_id |
280 will simply call this function to do the work. It will also pass the WebNode_id |
250 as a parameter. |
281 as a parameter. |
251 """ |
282 """ |
252 try: |
283 try: |
253 return _TCPclient_list[node_id]["WebviewConfiguration"][argument.name] |
284 return _WebNodeList[WebNode_id]["WebviewConfiguration"][argument.name] |
254 except Exception: |
285 except Exception: |
255 return "" |
286 return "" |
256 |
287 |
257 |
288 |
258 |
289 |
259 |
290 |
260 def _updateWebInterface(node_id): |
291 def _updateWebInterface(WebNode_id): |
261 """ |
292 """ |
262 Add/Remove buttons to/from the web interface depending on the current state |
293 Add/Remove buttons to/from the web interface depending on the current state |
263 - If there is a saved state => add a delete saved state button |
294 - If there is a saved state => add a delete saved state button |
264 """ |
295 """ |
265 |
296 |
266 config_hash = _TCPclient_list[node_id]["config_hash"] |
297 config_hash = _WebNodeList[WebNode_id]["config_hash"] |
267 config_name = _TCPclient_list[node_id]["config_name"] |
298 config_name = _WebNodeList[WebNode_id]["config_name"] |
268 |
299 |
269 # Add a "Delete Saved Configuration" button if there is a saved configuration! |
300 # Add a "Delete Saved Configuration" button if there is a saved configuration! |
270 if _TCPclient_list[node_id]["SavedConfiguration"] is None: |
301 if _WebNodeList[WebNode_id]["SavedConfiguration"] is None: |
271 _NS.ConfigurableSettings.delSettings("ModbusConfigDelSaved" + config_hash) |
302 _NS.ConfigurableSettings.delSettings("ModbusConfigDelSaved" + config_hash) |
272 else: |
303 else: |
273 def __OnButtonDel(**kwargs): |
304 def __OnButtonDel(**kwargs): |
274 return OnButtonDel(node_id = node_id, **kwargs) |
305 return OnButtonDel(WebNode_id = WebNode_id, **kwargs) |
275 |
306 |
276 _NS.ConfigurableSettings.addSettings( |
307 _NS.ConfigurableSettings.addSettings( |
277 "ModbusConfigDelSaved" + config_hash, # name (internal, may not contain spaces, ...) |
308 "ModbusConfigDelSaved" + config_hash, # name (internal, may not contain spaces, ...) |
278 _("Modbus Configuration: ") + config_name, # description (user visible label) |
309 _("Modbus Configuration: ") + config_name, # description (user visible label) |
279 [], # fields (empty, no parameters required!) |
310 [], # fields (empty, no parameters required!) |
289 The function will configure the Modbus plugin in the PLC with the values |
320 The function will configure the Modbus plugin in the PLC with the values |
290 specified in the web interface. However, values must be validated first! |
321 specified in the web interface. However, values must be validated first! |
291 |
322 |
292 Note that this function does not get called directly. The real callback |
323 Note that this function does not get called directly. The real callback |
293 function is the dynamic __OnButtonSave() function, which will add the |
324 function is the dynamic __OnButtonSave() function, which will add the |
294 "node_id" argument, and call this function to do the work. |
325 "WebNode_id" argument, and call this function to do the work. |
295 """ |
326 """ |
296 |
327 |
297 #_plcobj.LogMessage("Modbus web server extension::OnButtonSave() Called") |
328 #_plcobj.LogMessage("Modbus web server extension::OnButtonSave() Called") |
298 |
329 |
299 newConfig = {} |
330 newConfig = {} |
300 node_id = kwargs.get("node_id", None) |
331 WebNode_id = kwargs.get("WebNode_id", None) |
301 addr_type = _TCPclient_list[node_id]["addr_type"] |
332 WebParamList = _WebNodeList[WebNode_id]["WebParamList"] |
302 |
333 |
303 for par_name, x1, x2, x3 in _client_parameters[addr_type]: |
334 for par_name, x1, x2, x3 in WebParamList: |
304 value = kwargs.get(par_name, None) |
335 value = kwargs.get(par_name, None) |
305 if value is not None: |
336 if value is not None: |
306 newConfig[par_name] = value |
337 newConfig[par_name] = value |
307 |
338 |
308 _TCPclient_list[node_id]["WebviewConfiguration"] = newConfig |
339 _WebNodeList[WebNode_id]["WebviewConfiguration"] = newConfig |
309 |
340 |
310 # First check if configuration is OK. |
341 # First check if configuration is OK. |
311 ## TODO... |
342 ## TODO... |
312 #if not _CheckWebConfiguration(newConfig): |
343 #if not _CheckWebConfiguration(newConfig): |
313 # return |
344 # return |
314 |
345 |
315 # store to file the new configuration so that |
346 # store to file the new configuration so that |
316 # we can recoup the configuration the next time the PLC |
347 # we can recoup the configuration the next time the PLC |
317 # has a cold start (i.e. when Beremiz_service.py is retarted) |
348 # has a cold start (i.e. when Beremiz_service.py is retarted) |
318 _SetSavedConfiguration(node_id, newConfig) |
349 _SetSavedConfiguration(WebNode_id, newConfig) |
319 |
350 |
320 # Configure PLC with the current Modbus parameters |
351 # Configure PLC with the current Modbus parameters |
321 _SetPLCConfiguration(node_id, newConfig) |
352 _SetPLCConfiguration(WebNode_id, newConfig) |
322 |
353 |
323 # File has just been created => Delete button must be shown on web interface! |
354 # File has just been created => Delete button must be shown on web interface! |
324 _updateWebInterface(node_id) |
355 _updateWebInterface(WebNode_id) |
325 |
356 |
326 |
357 |
327 |
358 |
328 |
359 |
329 def OnButtonDel(**kwargs): |
360 def OnButtonDel(**kwargs): |
359 Function called when user clicks 'Show Current PLC Configuration' button in web interface |
390 Function called when user clicks 'Show Current PLC Configuration' button in web interface |
360 The function will load the current PLC configuration into the web form |
391 The function will load the current PLC configuration into the web form |
361 |
392 |
362 Note that this function does not get called directly. The real callback |
393 Note that this function does not get called directly. The real callback |
363 function is the dynamic __OnButtonShowCur() function, which will add the |
394 function is the dynamic __OnButtonShowCur() function, which will add the |
364 "node_id" argument, and call this function to do the work. |
395 "WebNode_id" argument, and call this function to do the work. |
365 """ |
396 """ |
366 node_id = kwargs.get("node_id", None) |
397 WebNode_id = kwargs.get("WebNode_id", None) |
367 |
398 |
368 _TCPclient_list[node_id]["WebviewConfiguration"] = _GetPLCConfiguration(node_id) |
399 _WebNodeList[WebNode_id]["WebviewConfiguration"] = _GetPLCConfiguration(WebNode_id) |
369 |
400 |
370 |
401 |
371 |
402 |
372 |
403 |
373 def _Load_TCP_Client(node_id): |
404 def _AddWebNode(C_node_id, WebParamListDict, GetParamFuncs, SetParamFuncs): |
374 TCPclient_entry = {} |
405 """ |
375 |
406 Load from the compiled code (.so file, aloready loaded into memmory) |
376 config_name = GetParamFuncs["config_name"](node_id) |
407 the configuration parameters of a specific Modbus plugin node. |
|
408 This function works with both client and server nodes, depending on the |
|
409 Get/SetParamFunc dictionaries passed to it (either the client or the server |
|
410 node versions of the Get/Set functions) |
|
411 """ |
|
412 WebNode_entry = {} |
|
413 |
|
414 config_name = GetParamFuncs["config_name"](C_node_id) |
377 # addr_type will be one of "tcp", "rtu" or "ascii" |
415 # addr_type will be one of "tcp", "rtu" or "ascii" |
378 addr_type = GetParamFuncs["addr_type" ](node_id) |
416 addr_type = GetParamFuncs["addr_type" ](C_node_id) |
379 # For some operations we cannot use the config name (e.g. filename to store config) |
417 # For some operations we cannot use the config name (e.g. filename to store config) |
380 # because the user may be using characters that are invalid for that purpose ('/' for |
418 # because the user may be using characters that are invalid for that purpose ('/' for |
381 # example), so we create a hash of the config_name, and use that instead. |
419 # example), so we create a hash of the config_name, and use that instead. |
382 config_hash = hashlib.md5(config_name).hexdigest() |
420 config_hash = hashlib.md5(config_name).hexdigest() |
383 |
421 |
384 _plcobj.LogMessage("Modbus web server extension::_Load_TCP_Client("+str(node_id)+") config_name="+config_name) |
422 #_plcobj.LogMessage("Modbus web server extension::_AddWebNode("+str(C_node_id)+") config_name="+config_name) |
385 |
423 |
386 # Add the new entry to the global list |
424 # Add the new entry to the global list |
387 # Note: it is OK, and actually necessary, to do this _before_ seting all the parameters in TCPclient_entry |
425 # Note: it is OK, and actually necessary, to do this _before_ seting all the parameters in WebNode_entry |
388 # TCPclient_entry will be stored as a reference, so we can insert parameters at will. |
426 # WebNode_entry will be stored as a reference, so we can later insert parameters at will. |
389 global _TCPclient_list |
427 global _WebNodeList |
390 _TCPclient_list.append(TCPclient_entry) |
428 _WebNodeList.append(WebNode_entry) |
391 |
429 WebNode_id = len(_WebNodeList) - 1 |
392 # store all node_id relevant data for future reference |
430 |
393 TCPclient_entry["node_id" ] = node_id |
431 # store all WebNode relevant data for future reference |
394 TCPclient_entry["config_name" ] = config_name |
432 # |
395 TCPclient_entry["addr_type" ] = addr_type |
433 # Note that "WebParamList" will reference one of: |
396 TCPclient_entry["config_hash" ] = config_hash |
434 # - TCPclient_parameters, TCPserver_parameters, RTUclient_parameters, RTUslave_parameters |
397 TCPclient_entry["filename" ] = os.path.join(_ModbusConfFiledir, "Modbus_config_" + config_hash + ".json") |
435 WebNode_entry["C_node_id" ] = C_node_id |
|
436 WebNode_entry["config_name" ] = config_name |
|
437 WebNode_entry["config_hash" ] = config_hash |
|
438 WebNode_entry["filename" ] = os.path.join(_ModbusConfFiledir, "Modbus_config_" + config_hash + ".json") |
|
439 WebNode_entry["GetParamFuncs"] = GetParamFuncs |
|
440 WebNode_entry["SetParamFuncs"] = SetParamFuncs |
|
441 WebNode_entry["WebParamList" ] = WebParamListDict[addr_type] |
398 |
442 |
399 # Dictionary that contains the Modbus configuration currently being shown |
443 # Dictionary that contains the Modbus configuration currently being shown |
400 # on the web interface |
444 # on the web interface |
401 # This configuration will almost always be identical to the current |
445 # This configuration will almost always be identical to the current |
402 # configuration in the PLC (i.e., the current state stored in the |
446 # configuration in the PLC (i.e., the current state stored in the |
403 # C variables in the .so file). |
447 # C variables in the .so file). |
404 # The configuration viewed on the web will only be different to the current |
448 # The configuration viewed on the web will only be different to the current |
405 # configuration when the user edits the configuration, and when |
449 # configuration when the user edits the configuration, and when |
406 # the user asks to save an edited configuration that contains an error. |
450 # the user asks to save an edited configuration that contains an error. |
407 TCPclient_entry["WebviewConfiguration"] = None |
451 WebNode_entry["WebviewConfiguration"] = None |
408 |
452 |
409 # Upon PLC load, this Dictionary is initialised with the Modbus configuration |
453 # Upon PLC load, this Dictionary is initialised with the Modbus configuration |
410 # hardcoded in the C file |
454 # hardcoded in the C file |
411 # (i.e. the configuration inserted in Beremiz IDE when project was compiled) |
455 # (i.e. the configuration inserted in Beremiz IDE when project was compiled) |
412 TCPclient_entry["DefaultConfiguration"] = _GetPLCConfiguration(node_id) |
456 WebNode_entry["DefaultConfiguration"] = _GetPLCConfiguration(WebNode_id) |
413 TCPclient_entry["WebviewConfiguration"] = TCPclient_entry["DefaultConfiguration"] |
457 WebNode_entry["WebviewConfiguration"] = WebNode_entry["DefaultConfiguration"] |
414 |
458 |
415 # Dictionary that stores the Modbus configuration currently stored in a file |
459 # Dictionary that stores the Modbus configuration currently stored in a file |
416 # Currently only used to decide whether or not to show the "Delete" button on the |
460 # Currently only used to decide whether or not to show the "Delete" button on the |
417 # web interface (only shown if _SavedConfiguration is not None) |
461 # web interface (only shown if "SavedConfiguration" is not None) |
418 SavedConfig = _GetSavedConfiguration(node_id) |
462 SavedConfig = _GetSavedConfiguration(WebNode_id) |
419 TCPclient_entry["SavedConfiguration"] = SavedConfig |
463 WebNode_entry["SavedConfiguration"] = SavedConfig |
420 |
464 |
421 if SavedConfig is not None: |
465 if SavedConfig is not None: |
422 _SetPLCConfiguration(node_id, SavedConfig) |
466 _SetPLCConfiguration(WebNode_id, SavedConfig) |
423 TCPclient_entry["WebviewConfiguration"] = SavedConfig |
467 WebNode_entry["WebviewConfiguration"] = SavedConfig |
424 |
468 |
425 # Define the format for the web form used to show/change the current parameters |
469 # Define the format for the web form used to show/change the current parameters |
426 # We first declare a dynamic function to work as callback to obtain the default values for each parameter |
470 # We first declare a dynamic function to work as callback to obtain the default values for each parameter |
427 def __GetWebviewConfigurationValue(ctx, argument): |
471 def __GetWebviewConfigurationValue(ctx, argument): |
428 return _GetWebviewConfigurationValue(ctx, node_id, argument) |
472 return _GetWebviewConfigurationValue(ctx, WebNode_id, argument) |
429 |
473 |
430 webFormInterface = [(name, web_dtype (label=web_label, default=__GetWebviewConfigurationValue)) |
474 webFormInterface = [(name, web_dtype (label=web_label, default=__GetWebviewConfigurationValue)) |
431 for name, web_label, c_dtype, web_dtype in _client_parameters[addr_type]] |
475 for name, web_label, c_dtype, web_dtype in WebParamListDict[addr_type]] |
432 |
476 |
433 # Configure the web interface to include the Modbus config parameters |
477 # Configure the web interface to include the Modbus config parameters |
434 def __OnButtonSave(**kwargs): |
478 def __OnButtonSave(**kwargs): |
435 OnButtonSave(node_id=node_id, **kwargs) |
479 OnButtonSave(WebNode_id=WebNode_id, **kwargs) |
436 |
480 |
437 _NS.ConfigurableSettings.addSettings( |
481 _NS.ConfigurableSettings.addSettings( |
438 "ModbusConfigParm" + config_hash, # name (internal, may not contain spaces, ...) |
482 "ModbusConfigParm" + config_hash, # name (internal, may not contain spaces, ...) |
439 _("Modbus Configuration: ") + config_name, # description (user visible label) |
483 _("Modbus Configuration: ") + config_name, # description (user visible label) |
440 webFormInterface, # fields |
484 webFormInterface, # fields |
441 _("Save Configuration to Persistent Storage"), # button label |
485 _("Save Configuration to Persistent Storage"), # button label |
442 __OnButtonSave) # callback |
486 __OnButtonSave) # callback |
443 |
487 |
444 # Add a "View Current Configuration" button |
488 # Add a "View Current Configuration" button |
445 def __OnButtonShowCur(**kwargs): |
489 def __OnButtonShowCur(**kwargs): |
446 OnButtonShowCur(node_id=node_id, **kwargs) |
490 OnButtonShowCur(WebNode_id=WebNode_id, **kwargs) |
447 |
491 |
448 _NS.ConfigurableSettings.addSettings( |
492 _NS.ConfigurableSettings.addSettings( |
449 "ModbusConfigViewCur" + config_hash, # name (internal, may not contain spaces, ...) |
493 "ModbusConfigViewCur" + config_hash, # name (internal, may not contain spaces, ...) |
450 _("Modbus Configuration: ") + config_name, # description (user visible label) |
494 _("Modbus Configuration: ") + config_name, # description (user visible label) |
451 [], # fields (empty, no parameters required!) |
495 [], # fields (empty, no parameters required!) |
452 _("Show Current PLC Configuration"), # button label |
496 _("Show Current PLC Configuration"), # button label |
453 __OnButtonShowCur) # callback |
497 __OnButtonShowCur) # callback |
454 |
498 |
455 # Add the Delete button to the web interface, if required |
499 # Add the Delete button to the web interface, if required |
456 _updateWebInterface(node_id) |
500 _updateWebInterface(WebNode_id) |
|
501 |
457 |
502 |
458 |
503 |
459 |
504 |
460 |
505 |
461 def OnLoadPLC(): |
506 def OnLoadPLC(): |
493 # The Modbus plugin in the loaded PLC does not have any client and servers configured |
538 # The Modbus plugin in the loaded PLC does not have any client and servers configured |
494 # => nothing to do (i.e. do _not_ configure and make available the Modbus web interface) |
539 # => nothing to do (i.e. do _not_ configure and make available the Modbus web interface) |
495 return |
540 return |
496 |
541 |
497 # Map the get/set functions (written in C code) we will be using to get/set the configuration parameters |
542 # Map the get/set functions (written in C code) we will be using to get/set the configuration parameters |
|
543 # Will contain references to the C functions (implemented in beremiz/modbus/mb_runtime.c) |
|
544 GetClientParamFuncs = {} |
|
545 SetClientParamFuncs = {} |
|
546 GetServerParamFuncs = {} |
|
547 SetServerParamFuncs = {} |
|
548 |
498 for name, web_label, c_dtype, web_dtype in TCPclient_parameters + RTUclient_parameters + General_parameters: |
549 for name, web_label, c_dtype, web_dtype in TCPclient_parameters + RTUclient_parameters + General_parameters: |
499 GetParamFuncName = "__modbus_get_ClientNode_" + name |
550 ParamFuncName = "__modbus_get_ClientNode_" + name |
500 GetParamFuncs[name] = getattr(_plcobj.PLClibraryHandle, GetParamFuncName) |
551 GetClientParamFuncs[name] = getattr(_plcobj.PLClibraryHandle, ParamFuncName) |
501 GetParamFuncs[name].restype = c_dtype |
552 GetClientParamFuncs[name].restype = c_dtype |
502 GetParamFuncs[name].argtypes = [ctypes.c_int] |
553 GetClientParamFuncs[name].argtypes = [ctypes.c_int] |
503 |
554 |
504 for name, web_label, c_dtype, web_dtype in TCPclient_parameters + RTUclient_parameters: |
555 for name, web_label, c_dtype, web_dtype in TCPclient_parameters + RTUclient_parameters: |
505 SetParamFuncName = "__modbus_set_ClientNode_" + name |
556 ParamFuncName = "__modbus_set_ClientNode_" + name |
506 SetParamFuncs[name] = getattr(_plcobj.PLClibraryHandle, SetParamFuncName) |
557 SetClientParamFuncs[name] = getattr(_plcobj.PLClibraryHandle, ParamFuncName) |
507 SetParamFuncs[name].restype = None |
558 SetClientParamFuncs[name].restype = None |
508 SetParamFuncs[name].argtypes = [ctypes.c_int, c_dtype] |
559 SetClientParamFuncs[name].argtypes = [ctypes.c_int, c_dtype] |
|
560 |
|
561 for name, web_label, c_dtype, web_dtype in TCPserver_parameters + RTUslave_parameters + General_parameters: |
|
562 ParamFuncName = "__modbus_get_ServerNode_" + name |
|
563 GetServerParamFuncs[name] = getattr(_plcobj.PLClibraryHandle, ParamFuncName) |
|
564 GetServerParamFuncs[name].restype = c_dtype |
|
565 GetServerParamFuncs[name].argtypes = [ctypes.c_int] |
|
566 |
|
567 for name, web_label, c_dtype, web_dtype in TCPserver_parameters + RTUslave_parameters: |
|
568 ParamFuncName = "__modbus_set_ServerNode_" + name |
|
569 SetServerParamFuncs[name] = getattr(_plcobj.PLClibraryHandle, ParamFuncName) |
|
570 SetServerParamFuncs[name].restype = None |
|
571 SetServerParamFuncs[name].argtypes = [ctypes.c_int, c_dtype] |
509 |
572 |
510 for node_id in range(client_count): |
573 for node_id in range(client_count): |
511 _Load_TCP_Client(node_id) |
574 _AddWebNode(node_id, _client_WebParamListDict ,GetClientParamFuncs, SetClientParamFuncs) |
512 |
575 |
|
576 for node_id in range(server_count): |
|
577 _AddWebNode(node_id, _server_WebParamListDict, GetServerParamFuncs, SetServerParamFuncs) |
513 |
578 |
514 |
579 |
515 |
580 |
516 |
581 |
517 |
582 |
518 def OnUnLoadPLC(): |
583 def OnUnLoadPLC(): |
519 """ |
584 """ |
520 # Callback function, called (by PLCObject.py) when a PLC program is unloaded from memory |
585 Callback function, called (by PLCObject.py) when a PLC program is unloaded from memory |
521 """ |
586 """ |
522 |
587 |
523 #_plcobj.LogMessage("Modbus web server extension::OnUnLoadPLC() Called...") |
588 #_plcobj.LogMessage("Modbus web server extension::OnUnLoadPLC() Called...") |
524 |
589 |
525 # Delete the Modbus specific web interface extensions |
590 # Delete the Modbus specific web interface extensions |
526 # (Safe to ask to delete, even if it has not been added!) |
591 # (Safe to ask to delete, even if it has not been added!) |
527 global _TCPclient_list |
592 global _WebNodeList |
528 for TCPclient_entry in _TCPclient_list: |
593 for WebNode_entry in _WebNodeList: |
529 config_hash = TCPclient_entry["config_hash"] |
594 config_hash = WebNode_entry["config_hash"] |
530 _NS.ConfigurableSettings.delSettings("ModbusConfigParm" + config_hash) |
595 _NS.ConfigurableSettings.delSettings("ModbusConfigParm" + config_hash) |
531 _NS.ConfigurableSettings.delSettings("ModbusConfigViewCur" + config_hash) |
596 _NS.ConfigurableSettings.delSettings("ModbusConfigViewCur" + config_hash) |
532 _NS.ConfigurableSettings.delSettings("ModbusConfigDelSaved" + config_hash) |
597 _NS.ConfigurableSettings.delSettings("ModbusConfigDelSaved" + config_hash) |
533 |
598 |
534 # Dele all entries... |
599 # Dele all entries... |
535 _TCPclient_list = [] |
600 _WebNodeList = [] |
536 |
601 |
537 |
602 |
538 |
603 |
539 # The Beremiz_service.py service, along with the integrated web server it launches |
604 # The Beremiz_service.py service, along with the integrated web server it launches |
540 # (i.e. Nevow web server, in runtime/NevowServer.py), will go through several states |
605 # (i.e. Nevow web server, in runtime/NevowServer.py), will go through several states |