lpcmanager

LPCCommand : switch to wx.Timer instead of regular python timer for the rapidfire protection. With regular python timers, some refresh order could pile eventloop when interacting with the GUI while doing initial loading of signals.
import wx
import csv
import os
def VariableWriter(parent, event, path):
FileDialog = wx.FileDialog(parent, "Save CSV file", "", "", "CSV files (*.csv)|*.csv",
wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
if FileDialog.ShowModal() == wx.ID_OK:
if FileDialog.GetPath()[-4:] == ".csv":
export = FileDialog.GetPath()
else:
export = FileDialog.GetPath() + ".csv"
else:
return
parent.Controler.logger.write(_("Exporting to " +export+" ...\n"))
modbus_list = []
modbus_dict = {}
setting_list = []
command_list = []
bit_dict = {}
program_name = ""
program_type = ""
with open(path + "\plc.xml") as infile:
for line in infile:
if "<pou" in line:
start_program = line.find("name")
if start_program != -1:
end_program = line[start_program:].find(" ")
program_name = line[start_program + 6:start_program + end_program - 1]
start_type = line.find("pouType")
if start_type != -1:
end_type = line[start_type:].find("\"")
program_type = line[start_type + 9:start_type + end_type + 8]
if ":= UINT_TO_WORD(" in line:
idx = line.find(":= UINT_TO_WORD(")
end = line[idx:].find(")")
name = line[idx + len(":= UINT_TO_WORD("):idx + end]
space = line.find(" ")
target = line[:space]
address = target.split("_")[-1]
modbus_list.append(name)
modbus_dict[name] = [target, address, program_name, program_type]
elif ":= WORD_TO_UINT(" in line and not "UINT_TO_WORD" in line:
idx = line.find(":= WORD_TO_UINT(")
end = line[idx:].find(")")
name = line[idx + len(":= WORD_TO_UINT("):idx + end]
space = line.find(" ")
target = line[:space]
address = name.split("_")[-1]
setting_list.append([target, "", "", "", "", name, address])
elif ":= WORD_TO_BOOL(" in line:
idx = line.find(":= WORD_TO_BOOL(")
end = line[idx + len(":= WORD_TO_BOOL("):].find(" ")
name = line[idx + len(":= WORD_TO_BOOL("):idx + len(":= WORD_TO_BOOL(") + end]
target = line[:idx].strip()
address = name.split("_")[-1]
bit_start = line.find(" N := ")
bit_end = line[bit_start:].find(")")
bit = line[bit_start + len(" N := "):bit_start + bit_end]
command_list.append([target, "", "", "", "", name, address+"."+bit])
elif ":= BOOL_TO_WORD(" in line:
idx = line.find(":= BOOL_TO_WORD(") + len(":= BOOL_TO_WORD(")
if "UINT_TO_BOOL(" in line[idx:]:
idx += len("UINT_TO_BOOL")
end = line[idx:].find(")")
else:
end = line[idx:].find(")")
name = line[idx:idx+end]
if "(*" in line:
target_start = len("(*")
else:
target_start = 0
target_end = line.find(" := ")
target = line[target_start:target_end].strip()
address = target.split("_")[-1]
if " N := " in line:
bit_start = line.find(" N := ")
bit_end = line[bit_start:].find(")")
bit = line[bit_start + len(" N := "):bit_start + bit_end]
bit_dict[name] = [target, address+"."+bit, program_name, program_type]
else:
bit_dict[name] = [target, address, program_name, program_type]
dir_list = [os.path.join(path, o) for o in os.listdir(path) if os.path.isdir(os.path.join(path, o))]
py_directories = []
for dir in dir_list:
if dir[-6:] == "py_ext":
py_directories.append(dir)
variables = [
["NAME", "DESCRIPTION", "TYPE", "GROUP", "SUBGROUP", "TYPE OF VARIABLE", "MODBUS NAME", "MODBUS ADDRESS", "PROGRAM NAME",
"PROGRAM TYPE"]]
for dir in py_directories:
variable_list = []
with open(dir + "\pyfile.xml") as infile:
for line in infile:
curr_variable = []
idx_name = line.find("name")
name = ""
if idx_name != -1:
end_name = line[idx_name:].find(" ")
name = line[idx_name + 6:idx_name + end_name - 1]
curr_variable.append(name)
idx_desc = line.find("desc")
desc = ""
if idx_desc != -1:
end_desc = line[idx_desc+7:].find("\"")
desc = line[idx_desc + 6:idx_desc + 7 + end_desc]
if len(curr_variable) > 0:
curr_variable.append(desc)
idx_type = line.find("type")
group = ""
type = ""
if idx_type != -1:
end_type = line[idx_type:].find(" ")
type = line[idx_type + 6:idx_type + end_type - 1]
group = dir.split("\\")[-1].split("@")[0]
if len(curr_variable) > 0:
curr_variable.append(type)
curr_variable.append(group)
idx_opts = line.find("opts")
options = []
if idx_opts != -1:
end_opts = line[idx_opts + 6:].find("\"")
opts = line[idx_opts + 6: idx_opts + end_opts + 6]
options = opts.split(" ")
o_type = ""
subgroup = ""
for o in options:
if o in ["Session", "Alarm", "Static"]:
o_type = o
if o == "scada":
o_type += " " + o
if o == "static":
o_type += " " + o
idx_subgroup = o.find("subgroup")
if idx_subgroup != -1:
subgroup = o[idx_subgroup + 9:]
if len(curr_variable) > 0:
curr_variable.append(subgroup)
curr_variable.append(o_type)
if len(curr_variable) > 0:
if name in modbus_list:
curr_variable += modbus_dict[name]
elif name in bit_dict:
curr_variable += bit_dict[name]
else:
curr_variable += ["", "", "", ""]
if curr_variable != []:
variables.append(curr_variable)
try:
with open(export, "wb") as f:
writer = csv.writer(f)
writer.writerows(variables)
writer = csv.writer(f)
writer.writerows([""])
writer.writerows(setting_list)
writer.writerows([""])
writer.writerows(command_list)
parent.Controler.logger.write(_("Export completed successfully.\n"))
except IOError:
dialog = wx.MessageDialog(parent, "File is oppened in another program. Please close it before exporting.", style= wx.OK | wx.ICON_EXCLAMATION)
dialog.ShowModal()
parent.Controler.logger.write_error(_("Export failed.\n"))