All register view and operation control working.

This commit is contained in:
Yeongdo Park 2020-02-19 14:30:17 -08:00
parent 17aebdf6d4
commit e2f3ad1ccd
5 changed files with 889 additions and 177 deletions

3
.gitignore vendored
View file

@ -1,3 +1,4 @@
/venv/ /venv/
*.bak *.bak
/__pycache__/ /__pycache__/
/#~wxg.autosave~faultView.wxg#

View file

@ -6,12 +6,17 @@
import wx import wx
import wx.grid import wx.grid
import wx.propgrid
import gettext import gettext
gettext.install(None) gettext.install(None)
from pubsub import pub from pubsub import pub
import re
from registers import regdict
print('pubsub API version', pub.VERSION_API) print('pubsub API version', pub.VERSION_API)
from pubsub.utils.notification import useNotifyByWriteFile from pubsub.utils.notification import useNotifyByWriteFile
@ -31,6 +36,7 @@ class Controller:
self.view = view self.view = view
self.timer = wx.Timer() self.timer = wx.Timer()
self.timer.Bind(wx.EVT_TIMER, self.OnTimer) self.timer.Bind(wx.EVT_TIMER, self.OnTimer)
self.refresh_rate = 2000
self.mode = False self.mode = False
pub.subscribe(self.getFaultInfo, 'fault_selected') pub.subscribe(self.getFaultInfo, 'fault_selected')
@ -40,9 +46,19 @@ class Controller:
pub.subscribe(self.resetNetworkConfigs, 'reset_network_configs') pub.subscribe(self.resetNetworkConfigs, 'reset_network_configs')
pub.subscribe(self.resetPcsRemote, 'reset_pcs_remote') pub.subscribe(self.resetPcsRemote, 'reset_pcs_remote')
pub.subscribe(self.checkSysOpMode, 'check_system_op_mode') pub.subscribe(self.checkSysOpMode, 'check_system_op_mode')
pub.subscribe(self.startSystemOp, "start_system_op_manual")
pub.subscribe(self.stopSystemOp, "stop_system_op_manual")
def startSystemOp(self, mode, val):
self.sc.setPortModes(mode)
self.sc.setPortSetpoints(val)
self.sc.setUserStart()
def stopSystemOp(self):
self.sc.setUserStop()
def startTimer(self): def startTimer(self):
self.timer.Start(2000) self.timer.Start(self.refresh_rate)
def stopTimer(self): def stopTimer(self):
self.timer.Stop() self.timer.Stop()
@ -50,6 +66,7 @@ class Controller:
def applyNetworkConfigs(self, ncDict): def applyNetworkConfigs(self, ncDict):
if self.sc: if self.sc:
self.sc.checkClose() self.sc.checkClose()
self.refresh_rate = ncDict.pop("refresh")
self.sc = SC(**ncDict) self.sc = SC(**ncDict)
def resetNetworkConfigs(self): def resetNetworkConfigs(self):
@ -84,14 +101,73 @@ class Controller:
self.view.text_fault_status.SetValue(status_text) self.view.text_fault_status.SetValue(status_text)
def OnTimer(self, event): def OnTimer(self, event):
# Read registers
self.sc.readAllRegisters()
# Process registers
# Show Registers
factivity = self.sc.readFaultActivity() factivity = self.sc.readFaultActivity()
foccurence = self.sc.readFaultOccurence() foccurence = self.sc.readFaultOccurence()
self.view.SetFaultGrid(factivity, foccurence) self.view.SetFaultGrid(factivity, foccurence)
event.Skip()
stats = list(range(4))
stats[0], _ = (self.sc.getSystemStatus())
stats[1], _ = (self.sc.getPortStatusAC1())
stats[2], _ = (self.sc.getPortStatusDC2())
stats[3], _ = (self.sc.getPortStatusDC3())
self.view.update_status(list(map("\n".join, stats)))
'''
for item in self.writeQueue:
name, value = item
self.sc.write(name, value)
'''
class MyFrame(FaultFrame): class MyFrame(FaultFrame):
def __init__(self, *args, **kwds): def __init__(self, *args, **kwds):
FaultFrame.__init__(self, *args, **kwds) FaultFrame.__init__(self, *args, **kwds)
self.property_page = self.property_grid_1.AddPage("Ports")
self.property_page_etc = self.property_grid_1.AddPage("Etc")
for k in regdict:
prop = wx.propgrid.StringProperty(label=k, value="")
prop.SetHelpString(str(regdict[k]))
if re.search(r'^p[1-3]_', k):
self.property_page.Append(prop)
else:
self.property_page_etc.Append(prop)
self.property_page.Sort()
self.property_page_etc.Sort()
# self.property_page.SetPropertyAttributeAll("Raw", 0)
# self.property_page_etc.SetPropertyAttributeAll("Raw", 0)
self.property_grid_1.SetPropertyAttributeAll("Units", 0)
self.property_grid_1.SetColumnCount(3, self.property_page.GetIndex())
self.property_grid_1.SetColumnCount(3, self.property_page_etc.GetIndex())
self.property_grid_1.ShowHeader()
pub.subscribe(self.update_display, 'read_all_registers')
def update_status(self, stats):
self.text_ctrl_system_status.SetValue(stats[0])
self.text_ctrl_ac1_status.SetValue(stats[1])
self.text_ctrl_dc2_status.SetValue(stats[2])
self.text_ctrl_dc3_status.SetValue(stats[3])
def update_display(self, reg, info):
ports = {k:v for (k,v) in info.items() if re.search(r'^p[1-3]_', k)}
etc = {k:v for (k,v) in info.items() if not re.search(r'^p[1-3]_', k)}
for k, v in ports.items():
self.property_page.SetPropertyValue(k, str(v.convertValue(reg[v.address])))
self.property_page.SetPropertyAttribute(k, "Units", str((reg[v.address])))
for k, v in etc.items():
self.property_page_etc.SetPropertyValue(k, str(v.convertValue(reg[v.address])))
self.property_page_etc.SetPropertyAttribute(k, "Units", str((reg[v.address])))
def OnFaultSelect(self, event): # wxGlade: MyFrame.<event_handler> def OnFaultSelect(self, event): # wxGlade: MyFrame.<event_handler>
pub.sendMessage("fault_selected", pos=(event.GetRow(), event.GetCol())) pub.sendMessage("fault_selected", pos=(event.GetRow(), event.GetCol()))
@ -103,8 +179,12 @@ class MyFrame(FaultFrame):
for j in range(8): for j in range(8):
if fActivity[i*8+j] == '1': if fActivity[i*8+j] == '1':
self.fault_grid.SetCellBackgroundColour(i, j, wx.LIGHT_GREY) self.fault_grid.SetCellBackgroundColour(i, j, wx.LIGHT_GREY)
else:
self.fault_grid.SetCellBackgroundColour(i, j, wx.WHITE)
if fOccurence[i*8+j] == '1': if fOccurence[i*8+j] == '1':
self.fault_grid.SetCellValue(i, j, "O") self.fault_grid.SetCellValue(i, j, "O")
else:
self.fault_grid.SetCellValue(i, j, "")
def ToggleMonitoring(self, event): # wxGlade: MyFrame.<event_handler> def ToggleMonitoring(self, event): # wxGlade: MyFrame.<event_handler>
btnLabel = self.button_1.GetLabel() btnLabel = self.button_1.GetLabel()
@ -115,9 +195,6 @@ class MyFrame(FaultFrame):
pub.sendMessage("monitoring_stopped") pub.sendMessage("monitoring_stopped")
self.button_1.SetLabel("Start") self.button_1.SetLabel("Start")
if event:
event.Skip()
def OnApply(self, event): def OnApply(self, event):
if self.button_1.Enabled: if self.button_1.Enabled:
@ -132,6 +209,7 @@ class MyFrame(FaultFrame):
"ipaddr": self.input_ip.GetValue(), "ipaddr": self.input_ip.GetValue(),
"port": int(self.input_port.GetValue()), "port": int(self.input_port.GetValue()),
"uid": int(self.input_uid.GetValue()), "uid": int(self.input_uid.GetValue()),
"refresh": int(self.input_refresh.GetValue()),
} }
pub.sendMessage("apply_network_configs", ncDict=ncDict) pub.sendMessage("apply_network_configs", ncDict=ncDict)
@ -161,6 +239,25 @@ class MyFrame(FaultFrame):
def OnCheckSysOpMode(self, event): def OnCheckSysOpMode(self, event):
pub.sendMessage("check_system_op_mode") pub.sendMessage("check_system_op_mode")
def OnOpStart(self, event):
mode = (self.choice_ac1_control.GetStringSelection(),
self.choice_dc2_control.GetStringSelection(),
self.choice_dc3_control.GetStringSelection())
inputs = {
"p1_real_pwr_setpt": self.text_ctrl_ac1_realpwr.Value,
"p1_react_pwr_setpt": self.text_ctrl_ac1_reactpwr.Value,
"p2_current_setpt": self.text_ctrl_dc2_current.Value,
"p2_power_setpt": self.text_ctrl_dc2_power.Value,
"p2_voltage_setpt": self.text_ctrl_dc2_voltage.Value,
"p3_current_setpt": self.text_ctrl_dc3_current.Value,
"p3_power_setpt": self.text_ctrl_dc3_power.Value,
"p3_voltage_setpt": self.text_ctrl_dc3_voltage.Value,
}
pub.sendMessage("start_system_op_manual", mode=mode, val=inputs)
def OnOpStop(self, event):
pub.sendMessage("stop_system_op_manual")
# end of class MyFrame # end of class MyFrame
class MyApp(wx.App): class MyApp(wx.App):

View file

@ -1,10 +1,11 @@
# -*- coding: UTF-8 -*- # -*- coding: UTF-8 -*-
# #
# generated by wxGlade 0.9.5 on Thu Feb 13 18:40:11 2020 # generated by wxGlade 0.9.5 on Tue Feb 18 18:22:15 2020
# #
import wx import wx
import wx.grid import wx.grid
import wx.propgrid
# begin wxGlade: dependencies # begin wxGlade: dependencies
import gettext import gettext
@ -19,7 +20,7 @@ class FaultFrame(wx.Frame):
# begin wxGlade: FaultFrame.__init__ # begin wxGlade: FaultFrame.__init__
kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds) wx.Frame.__init__(self, *args, **kwds)
self.SetSize((632, 556)) self.SetSize((1099, 729))
self.input_ip = wx.TextCtrl(self, wx.ID_ANY, _("192.168.1.21")) self.input_ip = wx.TextCtrl(self, wx.ID_ANY, _("192.168.1.21"))
self.input_port = wx.TextCtrl(self, wx.ID_ANY, _("502")) self.input_port = wx.TextCtrl(self, wx.ID_ANY, _("502"))
self.input_uid = wx.TextCtrl(self, wx.ID_ANY, _("240")) self.input_uid = wx.TextCtrl(self, wx.ID_ANY, _("240"))
@ -27,13 +28,35 @@ class FaultFrame(wx.Frame):
self.reset_button = wx.Button(self, wx.ID_ANY, _("Reset Connection")) self.reset_button = wx.Button(self, wx.ID_ANY, _("Reset Connection"))
self.apply_button = wx.Button(self, wx.ID_ANY, _("Apply")) self.apply_button = wx.Button(self, wx.ID_ANY, _("Apply"))
self.rreset_button = wx.Button(self, wx.ID_ANY, _("Remote PCS Reset")) self.rreset_button = wx.Button(self, wx.ID_ANY, _("Remote PCS Reset"))
self.some_button = wx.Button(self, wx.ID_STOP, "") self.button_1 = wx.ToggleButton(self, wx.ID_ANY, _("Start"))
self.op_mode_button = wx.Button(self, wx.ID_ANY, _("System OP Mode")) self.op_mode_button = wx.Button(self, wx.ID_ANY, _("System OP Mode"))
self.text_op_mode = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_READONLY) self.text_op_mode = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_READONLY)
self.text_ctrl_system_status = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE | wx.TE_READONLY)
self.text_ctrl_ac1_status = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE | wx.TE_READONLY)
self.text_ctrl_dc2_status = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE | wx.TE_READONLY)
self.text_ctrl_dc3_status = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE | wx.TE_READONLY)
self.fault_grid = wx.grid.Grid(self, wx.ID_ANY, size=(1, 1)) self.fault_grid = wx.grid.Grid(self, wx.ID_ANY, size=(1, 1))
self.button_1 = wx.ToggleButton(self, wx.ID_ANY, _("Start"))
self.text_fault_doc = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE | wx.TE_READONLY) self.text_fault_doc = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE | wx.TE_READONLY)
self.text_fault_status = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE | wx.TE_READONLY) self.text_fault_status = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE | wx.TE_READONLY)
self.panel_1 = wx.Panel(self, wx.ID_ANY)
self.button_2 = wx.Button(self.panel_1, wx.ID_ANY, _("Start"))
self.button_3 = wx.Button(self.panel_1, wx.ID_ANY, _("Stop"))
self.choice_ac1_control = wx.Choice(self.panel_1, wx.ID_ANY, choices=[_("IDLE"), _("NET"), _("GPWR"), _("FPWR")])
self.text_ctrl_ac1_realpwr = wx.TextCtrl(self.panel_1, wx.ID_ANY, _("0"))
self.text_ctrl_ac1_reactpwr = wx.TextCtrl(self.panel_1, wx.ID_ANY, _("0"))
self.choice_dc2_control = wx.Choice(self.panel_1, wx.ID_ANY, choices=[_("IDLE"), _("NET"), _("PV/MPPT"), _("CURR"), _("PWR"), _("VOLT")])
self.text_ctrl_dc2_current = wx.TextCtrl(self.panel_1, wx.ID_ANY, _("0"))
self.text_ctrl_dc2_power = wx.TextCtrl(self.panel_1, wx.ID_ANY, _("0"))
self.text_ctrl_dc2_voltage = wx.TextCtrl(self.panel_1, wx.ID_ANY, _("0"))
self.text_ctrl_7 = wx.TextCtrl(self.panel_1, wx.ID_ANY, "")
self.text_ctrl_8 = wx.TextCtrl(self.panel_1, wx.ID_ANY, "")
self.button_4 = wx.Button(self.panel_1, wx.ID_ANY, _("Enable Precharge"))
self.button_5 = wx.Button(self.panel_1, wx.ID_ANY, _("Disable Precharge"))
self.choice_dc3_control = wx.Choice(self.panel_1, wx.ID_ANY, choices=[_("IDLE"), _("NET"), _("PV/MPPT"), _("CURR"), _("PWR"), _("VOLT")])
self.text_ctrl_dc3_current = wx.TextCtrl(self.panel_1, wx.ID_ANY, _("0"))
self.text_ctrl_dc3_power = wx.TextCtrl(self.panel_1, wx.ID_ANY, _("0"))
self.text_ctrl_dc3_voltage = wx.TextCtrl(self.panel_1, wx.ID_ANY, _("0"))
self.property_grid_1 = wx.propgrid.PropertyGridManager(self, wx.ID_ANY, style=wx.propgrid.PG_DESCRIPTION | wx.propgrid.PG_TOOLBAR)
self.__set_properties() self.__set_properties()
self.__do_layout() self.__do_layout()
@ -41,14 +64,18 @@ class FaultFrame(wx.Frame):
self.Bind(wx.EVT_BUTTON, self.OnReset, self.reset_button) self.Bind(wx.EVT_BUTTON, self.OnReset, self.reset_button)
self.Bind(wx.EVT_BUTTON, self.OnApply, self.apply_button) self.Bind(wx.EVT_BUTTON, self.OnApply, self.apply_button)
self.Bind(wx.EVT_BUTTON, self.OnButtonRemoteReset, self.rreset_button) self.Bind(wx.EVT_BUTTON, self.OnButtonRemoteReset, self.rreset_button)
self.Bind(wx.EVT_TOGGLEBUTTON, self.ToggleMonitoring, self.button_1)
self.Bind(wx.EVT_BUTTON, self.OnCheckSysOpMode, self.op_mode_button) self.Bind(wx.EVT_BUTTON, self.OnCheckSysOpMode, self.op_mode_button)
self.Bind(wx.grid.EVT_GRID_CMD_CELL_LEFT_CLICK, self.OnFaultSelect, self.fault_grid) self.Bind(wx.grid.EVT_GRID_CMD_CELL_LEFT_CLICK, self.OnFaultSelect, self.fault_grid)
self.Bind(wx.EVT_TOGGLEBUTTON, self.ToggleMonitoring, self.button_1) self.Bind(wx.EVT_BUTTON, self.OnOpStart, self.button_2)
self.Bind(wx.EVT_BUTTON, self.OnOpStop, self.button_3)
# end wxGlade # end wxGlade
def __set_properties(self): def __set_properties(self):
# begin wxGlade: FaultFrame.__set_properties # begin wxGlade: FaultFrame.__set_properties
self.SetTitle(_("frame")) self.SetTitle(_("PCS Controller"))
self.rreset_button.Enable(False)
self.button_1.Enable(False)
self.fault_grid.CreateGrid(8, 8) self.fault_grid.CreateGrid(8, 8)
self.fault_grid.SetRowLabelSize(30) self.fault_grid.SetRowLabelSize(30)
self.fault_grid.SetColLabelSize(30) self.fault_grid.SetColLabelSize(30)
@ -73,16 +100,25 @@ class FaultFrame(wx.Frame):
self.fault_grid.SetRowSize(6, 30) self.fault_grid.SetRowSize(6, 30)
self.fault_grid.SetRowSize(7, 30) self.fault_grid.SetRowSize(7, 30)
self.fault_grid.SetMinSize((270, 270)) self.fault_grid.SetMinSize((270, 270))
self.button_1.Enable(False) self.choice_ac1_control.SetSelection(0)
self.text_fault_doc.SetMinSize((-1, 120)) self.choice_dc2_control.SetSelection(0)
self.text_fault_status.SetMinSize((-1, 120)) self.choice_dc3_control.SetSelection(0)
# end wxGlade # end wxGlade
def __do_layout(self): def __do_layout(self):
# begin wxGlade: FaultFrame.__do_layout # begin wxGlade: FaultFrame.__do_layout
sizer_1 = wx.BoxSizer(wx.HORIZONTAL) sizer_1 = wx.BoxSizer(wx.HORIZONTAL)
sizer_2 = wx.BoxSizer(wx.VERTICAL)
sizer_11 = wx.StaticBoxSizer(wx.StaticBox(self.panel_1, wx.ID_ANY, _("DC3 Port")), wx.HORIZONTAL)
grid_sizer_2 = wx.GridSizer(4, 2, 0, 0)
sizer_10 = wx.StaticBoxSizer(wx.StaticBox(self.panel_1, wx.ID_ANY, _("DC2 Port")), wx.HORIZONTAL)
grid_sizer_1 = wx.GridSizer(7, 2, 0, 0)
sizer_9 = wx.StaticBoxSizer(wx.StaticBox(self.panel_1, wx.ID_ANY, _("AC1 Port")), wx.HORIZONTAL)
grid_sizer_3 = wx.GridSizer(3, 2, 0, 0)
sizer_5 = wx.StaticBoxSizer(wx.StaticBox(self.panel_1, wx.ID_ANY, _("Manual Mode Control")), wx.HORIZONTAL)
sizer_3 = wx.BoxSizer(wx.VERTICAL) sizer_3 = wx.BoxSizer(wx.VERTICAL)
sizer_2 = wx.BoxSizer(wx.HORIZONTAL) sizer_7 = wx.BoxSizer(wx.VERTICAL)
sizer_8 = wx.BoxSizer(wx.VERTICAL)
sizer_4 = wx.GridSizer(7, 2, 0, 0) sizer_4 = wx.GridSizer(7, 2, 0, 0)
label_1 = wx.StaticText(self, wx.ID_ANY, _("IP Address")) label_1 = wx.StaticText(self, wx.ID_ANY, _("IP Address"))
sizer_4.Add(label_1, 0, 0, 0) sizer_4.Add(label_1, 0, 0, 0)
@ -99,16 +135,85 @@ class FaultFrame(wx.Frame):
sizer_4.Add(self.reset_button, 0, 0, 0) sizer_4.Add(self.reset_button, 0, 0, 0)
sizer_4.Add(self.apply_button, 0, 0, 0) sizer_4.Add(self.apply_button, 0, 0, 0)
sizer_4.Add(self.rreset_button, 0, 0, 0) sizer_4.Add(self.rreset_button, 0, 0, 0)
sizer_4.Add(self.some_button, 0, 0, 0) sizer_4.Add(self.button_1, 0, 0, 0)
sizer_4.Add(self.op_mode_button, 0, 0, 0) sizer_4.Add(self.op_mode_button, 0, 0, 0)
sizer_4.Add(self.text_op_mode, 0, 0, 0) sizer_4.Add(self.text_op_mode, 0, 0, 0)
sizer_1.Add(sizer_4, 1, wx.EXPAND, 0) sizer_7.Add(sizer_4, 0, wx.EXPAND, 0)
sizer_2.Add(self.fault_grid, 0, wx.ALIGN_CENTER, 0) label_21 = wx.StaticText(self, wx.ID_ANY, _("System Status"))
sizer_2.Add(self.button_1, 0, wx.ALIGN_CENTER, 0) sizer_8.Add(label_21, 0, 0, 0)
sizer_3.Add(sizer_2, 1, wx.ALIGN_CENTER, 0) sizer_8.Add(self.text_ctrl_system_status, 1, wx.EXPAND, 0)
sizer_3.Add(self.text_fault_doc, 0, wx.EXPAND, 0) label_22 = wx.StaticText(self, wx.ID_ANY, _("AC1 Status"))
sizer_3.Add(self.text_fault_status, 0, wx.EXPAND, 0) sizer_8.Add(label_22, 0, 0, 0)
sizer_8.Add(self.text_ctrl_ac1_status, 1, wx.EXPAND, 0)
label_23 = wx.StaticText(self, wx.ID_ANY, _("DC2 Statu"))
sizer_8.Add(label_23, 0, 0, 0)
sizer_8.Add(self.text_ctrl_dc2_status, 1, wx.EXPAND, 0)
label_24 = wx.StaticText(self, wx.ID_ANY, _("DC3 Status"))
sizer_8.Add(label_24, 0, 0, 0)
sizer_8.Add(self.text_ctrl_dc3_status, 1, wx.EXPAND, 0)
sizer_7.Add(sizer_8, 1, wx.EXPAND, 0)
sizer_1.Add(sizer_7, 1, wx.EXPAND, 0)
sizer_3.Add(self.fault_grid, 0, wx.ALIGN_CENTER, 0)
label_25 = wx.StaticText(self, wx.ID_ANY, _("Fault Info (Documented)"))
sizer_3.Add(label_25, 0, 0, 0)
sizer_3.Add(self.text_fault_doc, 1, wx.EXPAND, 0)
label_26 = wx.StaticText(self, wx.ID_ANY, _("Fault Status"))
sizer_3.Add(label_26, 0, 0, 0)
sizer_3.Add(self.text_fault_status, 1, wx.EXPAND, 0)
sizer_1.Add(sizer_3, 1, wx.EXPAND, 0) sizer_1.Add(sizer_3, 1, wx.EXPAND, 0)
sizer_5.Add(self.button_2, 0, 0, 0)
sizer_5.Add(self.button_3, 0, 0, 0)
sizer_2.Add(sizer_5, 0, 0, 0)
label_8 = wx.StaticText(self.panel_1, wx.ID_ANY, _("Control Method"))
grid_sizer_3.Add(label_8, 0, 0, 0)
grid_sizer_3.Add(self.choice_ac1_control, 0, 0, 0)
label_11 = wx.StaticText(self.panel_1, wx.ID_ANY, _("Real Power Setpoint"))
grid_sizer_3.Add(label_11, 0, 0, 0)
grid_sizer_3.Add(self.text_ctrl_ac1_realpwr, 0, 0, 0)
label_12 = wx.StaticText(self.panel_1, wx.ID_ANY, _("Reactive Power Setpoint"))
grid_sizer_3.Add(label_12, 0, 0, 0)
grid_sizer_3.Add(self.text_ctrl_ac1_reactpwr, 0, 0, 0)
sizer_9.Add(grid_sizer_3, 1, wx.EXPAND, 0)
sizer_2.Add(sizer_9, 1, wx.EXPAND, 0)
label_9 = wx.StaticText(self.panel_1, wx.ID_ANY, _("Contol Method"))
grid_sizer_1.Add(label_9, 0, 0, 0)
grid_sizer_1.Add(self.choice_dc2_control, 0, 0, 0)
label_19 = wx.StaticText(self.panel_1, wx.ID_ANY, _("Current Setpoint"))
grid_sizer_1.Add(label_19, 0, 0, 0)
grid_sizer_1.Add(self.text_ctrl_dc2_current, 0, 0, 0)
label_13 = wx.StaticText(self.panel_1, wx.ID_ANY, _("Power Setpoint"))
grid_sizer_1.Add(label_13, 0, 0, 0)
grid_sizer_1.Add(self.text_ctrl_dc2_power, 0, 0, 0)
label_14 = wx.StaticText(self.panel_1, wx.ID_ANY, _("Voltage Setpoint"))
grid_sizer_1.Add(label_14, 0, 0, 0)
grid_sizer_1.Add(self.text_ctrl_dc2_voltage, 0, 0, 0)
label_17 = wx.StaticText(self.panel_1, wx.ID_ANY, _("Precharge Limit Low"))
grid_sizer_1.Add(label_17, 0, 0, 0)
label_18 = wx.StaticText(self.panel_1, wx.ID_ANY, _("Precharge Limit High"))
grid_sizer_1.Add(label_18, 0, 0, 0)
grid_sizer_1.Add(self.text_ctrl_7, 0, 0, 0)
grid_sizer_1.Add(self.text_ctrl_8, 0, 0, 0)
grid_sizer_1.Add(self.button_4, 0, 0, 0)
grid_sizer_1.Add(self.button_5, 0, 0, 0)
sizer_10.Add(grid_sizer_1, 1, wx.EXPAND, 0)
sizer_2.Add(sizer_10, 1, wx.EXPAND, 0)
label_10 = wx.StaticText(self.panel_1, wx.ID_ANY, _("Control Method"))
grid_sizer_2.Add(label_10, 0, 0, 0)
grid_sizer_2.Add(self.choice_dc3_control, 0, 0, 0)
label_20 = wx.StaticText(self.panel_1, wx.ID_ANY, _("Current Setpoint"))
grid_sizer_2.Add(label_20, 0, 0, 0)
grid_sizer_2.Add(self.text_ctrl_dc3_current, 0, 0, 0)
label_15 = wx.StaticText(self.panel_1, wx.ID_ANY, _("Power Setpoint"))
grid_sizer_2.Add(label_15, 0, 0, 0)
grid_sizer_2.Add(self.text_ctrl_dc3_power, 0, 0, 0)
label_16 = wx.StaticText(self.panel_1, wx.ID_ANY, _("Voltage Setpoint"))
grid_sizer_2.Add(label_16, 0, 0, 0)
grid_sizer_2.Add(self.text_ctrl_dc3_voltage, 0, 0, 0)
sizer_11.Add(grid_sizer_2, 1, wx.ALL | wx.EXPAND, 1)
sizer_2.Add(sizer_11, 1, wx.EXPAND, 0)
self.panel_1.SetSizer(sizer_2)
sizer_1.Add(self.panel_1, 1, wx.EXPAND, 0)
sizer_1.Add(self.property_grid_1, 1, wx.EXPAND, 0)
self.SetSizer(sizer_1) self.SetSizer(sizer_1)
self.Layout() self.Layout()
# end wxGlade # end wxGlade
@ -125,6 +230,10 @@ class FaultFrame(wx.Frame):
print("Event handler 'OnButtonRemoteReset' not implemented!") print("Event handler 'OnButtonRemoteReset' not implemented!")
event.Skip() event.Skip()
def ToggleMonitoring(self, event): # wxGlade: FaultFrame.<event_handler>
print("Event handler 'ToggleMonitoring' not implemented!")
event.Skip()
def OnCheckSysOpMode(self, event): # wxGlade: FaultFrame.<event_handler> def OnCheckSysOpMode(self, event): # wxGlade: FaultFrame.<event_handler>
print("Event handler 'OnCheckSysOpMode' not implemented!") print("Event handler 'OnCheckSysOpMode' not implemented!")
event.Skip() event.Skip()
@ -133,8 +242,12 @@ class FaultFrame(wx.Frame):
print("Event handler 'OnFaultSelect' not implemented!") print("Event handler 'OnFaultSelect' not implemented!")
event.Skip() event.Skip()
def ToggleMonitoring(self, event): # wxGlade: FaultFrame.<event_handler> def OnOpStart(self, event): # wxGlade: FaultFrame.<event_handler>
print("Event handler 'ToggleMonitoring' not implemented!") print("Event handler 'OnOpStart' not implemented!")
event.Skip()
def OnOpStop(self, event): # wxGlade: FaultFrame.<event_handler>
print("Event handler 'OnOpStop' not implemented!")
event.Skip() event.Skip()
# end of class FaultFrame # end of class FaultFrame

View file

@ -1,10 +1,10 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<!-- generated by wxGlade 0.9.5 on Thu Feb 13 19:39:40 2020 --> <!-- generated by wxGlade 0.9.5 on Tue Feb 18 18:24:41 2020 -->
<application encoding="UTF-8" for_version="3.0" header_extension=".h" indent_amount="4" indent_symbol="space" is_template="0" language="python" mark_blocks="0" option="0" overwrite="1" path="FaultView.py" source_extension=".cpp" top_window="frame" use_gettext="1" use_new_namespace="1"> <application encoding="UTF-8" for_version="3.0" header_extension=".h" indent_amount="4" indent_symbol="space" is_template="0" language="python" mark_blocks="0" option="0" overwrite="1" path="FaultView.py" source_extension=".cpp" top_window="frame" use_gettext="1" use_new_namespace="1">
<object class="FaultFrame" name="frame" base="EditFrame"> <object class="FaultFrame" name="frame" base="EditFrame">
<size>558, 556</size> <size>1099, 729</size>
<title>frame</title> <title>PCS Controller</title>
<style>wxDEFAULT_FRAME_STYLE</style> <style>wxDEFAULT_FRAME_STYLE</style>
<object class="wxBoxSizer" name="sizer_1" base="EditBoxSizer"> <object class="wxBoxSizer" name="sizer_1" base="EditBoxSizer">
<orient>wxHORIZONTAL</orient> <orient>wxHORIZONTAL</orient>
@ -12,123 +12,200 @@
<option>1</option> <option>1</option>
<border>0</border> <border>0</border>
<flag>wxEXPAND</flag> <flag>wxEXPAND</flag>
<object class="wxGridSizer" name="sizer_4" base="EditGridSizer"> <object class="wxBoxSizer" name="sizer_7" base="EditBoxSizer">
<rows>7</rows> <orient>wxVERTICAL</orient>
<cols>2</cols>
<vgap>0</vgap>
<hgap>0</hgap>
<object class="sizeritem"> <object class="sizeritem">
<option>0</option> <option>0</option>
<border>0</border> <border>0</border>
<object class="wxStaticText" name="label_1" base="EditStaticText"> <flag>wxEXPAND</flag>
<label>IP Address</label> <object class="wxGridSizer" name="sizer_4" base="EditGridSizer">
<rows>7</rows>
<cols>2</cols>
<vgap>0</vgap>
<hgap>0</hgap>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxStaticText" name="label_1" base="EditStaticText">
<label>IP Address</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxTextCtrl" name="input_ip" base="EditTextCtrl">
<value>192.168.1.21</value>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxStaticText" name="label_2" base="EditStaticText">
<label>Port</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxTextCtrl" name="input_port" base="EditTextCtrl">
<value>502</value>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxStaticText" name="label_3" base="EditStaticText">
<label>Unit ID</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxTextCtrl" name="input_uid" base="EditTextCtrl">
<value>240</value>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxStaticText" name="label_4" base="EditStaticText">
<label>Refresh Period (ms)</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxTextCtrl" name="input_refresh" base="EditTextCtrl">
<value>2000</value>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxButton" name="reset_button" base="EditButton">
<events>
<handler event="EVT_BUTTON">OnReset</handler>
</events>
<label>Reset Connection</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxButton" name="apply_button" base="EditButton">
<events>
<handler event="EVT_BUTTON">OnApply</handler>
</events>
<label>Apply</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxButton" name="rreset_button" base="EditButton">
<events>
<handler event="EVT_BUTTON">OnButtonRemoteReset</handler>
</events>
<disabled>1</disabled>
<label>Remote PCS Reset</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxToggleButton" name="button_1" base="EditToggleButton">
<events>
<handler event="EVT_TOGGLEBUTTON">ToggleMonitoring</handler>
</events>
<disabled>1</disabled>
<label>Start</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxButton" name="op_mode_button" base="EditButton">
<events>
<handler event="EVT_BUTTON">OnCheckSysOpMode</handler>
</events>
<label>System OP Mode</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxTextCtrl" name="text_op_mode" base="EditTextCtrl">
<style>wxTE_READONLY</style>
</object>
</object>
</object> </object>
</object> </object>
<object class="sizeritem"> <object class="sizeritem">
<option>0</option> <option>1</option>
<border>0</border> <border>0</border>
<object class="wxTextCtrl" name="input_ip" base="EditTextCtrl"> <flag>wxEXPAND</flag>
<value>192.168.1.21</value> <object class="wxBoxSizer" name="sizer_8" base="EditBoxSizer">
</object> <orient>wxVERTICAL</orient>
</object> <object class="sizeritem">
<object class="sizeritem"> <option>0</option>
<option>0</option> <border>0</border>
<border>0</border> <object class="wxStaticText" name="label_21" base="EditStaticText">
<object class="wxStaticText" name="label_2" base="EditStaticText"> <label>System Status</label>
<label>Port</label> </object>
</object> </object>
</object> <object class="sizeritem">
<object class="sizeritem"> <option>1</option>
<option>0</option> <border>0</border>
<border>0</border> <flag>wxEXPAND</flag>
<object class="wxTextCtrl" name="input_port" base="EditTextCtrl"> <object class="wxTextCtrl" name="text_ctrl_system_status" base="EditTextCtrl">
<value>502</value> <style>wxTE_MULTILINE|wxTE_READONLY</style>
</object> </object>
</object> </object>
<object class="sizeritem"> <object class="sizeritem">
<option>0</option> <option>0</option>
<border>0</border> <border>0</border>
<object class="wxStaticText" name="label_3" base="EditStaticText"> <object class="wxStaticText" name="label_22" base="EditStaticText">
<label>Unit ID</label> <label>AC1 Status</label>
</object> </object>
</object> </object>
<object class="sizeritem"> <object class="sizeritem">
<option>0</option> <option>1</option>
<border>0</border> <border>0</border>
<object class="wxTextCtrl" name="input_uid" base="EditTextCtrl"> <flag>wxEXPAND</flag>
<value>240</value> <object class="wxTextCtrl" name="text_ctrl_ac1_status" base="EditTextCtrl">
</object> <style>wxTE_MULTILINE|wxTE_READONLY</style>
</object> </object>
<object class="sizeritem"> </object>
<option>0</option> <object class="sizeritem">
<border>0</border> <option>0</option>
<object class="wxStaticText" name="label_4" base="EditStaticText"> <border>0</border>
<label>Refresh Period (ms)</label> <object class="wxStaticText" name="label_23" base="EditStaticText">
</object> <label>DC2 Statu</label>
</object> </object>
<object class="sizeritem"> </object>
<option>0</option> <object class="sizeritem">
<border>0</border> <option>1</option>
<object class="wxTextCtrl" name="input_refresh" base="EditTextCtrl"> <border>0</border>
<value>2000</value> <flag>wxEXPAND</flag>
</object> <object class="wxTextCtrl" name="text_ctrl_dc2_status" base="EditTextCtrl">
</object> <style>wxTE_MULTILINE|wxTE_READONLY</style>
<object class="sizeritem"> </object>
<option>0</option> </object>
<border>0</border> <object class="sizeritem">
<object class="wxButton" name="reset_button" base="EditButton"> <option>0</option>
<events> <border>0</border>
<handler event="EVT_BUTTON">OnReset</handler> <object class="wxStaticText" name="label_24" base="EditStaticText">
</events> <label>DC3 Status</label>
<label>Reset Connection</label> </object>
</object> </object>
</object> <object class="sizeritem">
<object class="sizeritem"> <option>1</option>
<option>0</option> <border>0</border>
<border>0</border> <flag>wxEXPAND</flag>
<object class="wxButton" name="apply_button" base="EditButton"> <object class="wxTextCtrl" name="text_ctrl_dc3_status" base="EditTextCtrl">
<events> <style>wxTE_MULTILINE|wxTE_READONLY</style>
<handler event="EVT_BUTTON">OnApply</handler> </object>
</events> </object>
<label>Apply</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxButton" name="rreset_button" base="EditButton">
<events>
<handler event="EVT_BUTTON">OnButtonRemoteReset</handler>
</events>
<label>Remote PCS Reset</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxToggleButton" name="button_1" base="EditToggleButton">
<events>
<handler event="EVT_TOGGLEBUTTON">ToggleMonitoring</handler>
</events>
<disabled>1</disabled>
<label>Start</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxButton" name="op_mode_button" base="EditButton">
<events>
<handler event="EVT_BUTTON">OnCheckSysOpMode</handler>
</events>
<label>System OP Mode</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxTextCtrl" name="text_op_mode" base="EditTextCtrl">
<style>wxTE_READONLY</style>
</object> </object>
</object> </object>
</object> </object>
@ -180,23 +257,358 @@
<object class="sizeritem"> <object class="sizeritem">
<option>0</option> <option>0</option>
<border>0</border> <border>0</border>
<object class="wxStaticText" name="label_25" base="EditStaticText">
<label>Fault Info (Documented)</label>
</object>
</object>
<object class="sizeritem">
<option>1</option>
<border>0</border>
<flag>wxEXPAND</flag> <flag>wxEXPAND</flag>
<object class="wxTextCtrl" name="text_fault_doc" base="EditTextCtrl"> <object class="wxTextCtrl" name="text_fault_doc" base="EditTextCtrl">
<size>-1, 120</size>
<style>wxTE_MULTILINE|wxTE_READONLY</style> <style>wxTE_MULTILINE|wxTE_READONLY</style>
</object> </object>
</object> </object>
<object class="sizeritem"> <object class="sizeritem">
<option>0</option> <option>0</option>
<border>0</border> <border>0</border>
<object class="wxStaticText" name="label_26" base="EditStaticText">
<label>Fault Status</label>
</object>
</object>
<object class="sizeritem">
<option>1</option>
<border>0</border>
<flag>wxEXPAND</flag> <flag>wxEXPAND</flag>
<object class="wxTextCtrl" name="text_fault_status" base="EditTextCtrl"> <object class="wxTextCtrl" name="text_fault_status" base="EditTextCtrl">
<size>-1, 120</size>
<style>wxTE_MULTILINE|wxTE_READONLY</style> <style>wxTE_MULTILINE|wxTE_READONLY</style>
</object> </object>
</object> </object>
</object> </object>
</object> </object>
<object class="sizeritem">
<option>1</option>
<border>0</border>
<flag>wxEXPAND</flag>
<object class="wxPanel" name="panel_1" base="EditPanel">
<object class="wxBoxSizer" name="sizer_2" base="EditBoxSizer">
<orient>wxVERTICAL</orient>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxStaticBoxSizer" name="sizer_5" base="EditStaticBoxSizer">
<orient>wxHORIZONTAL</orient>
<label>Manual Mode Control</label>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxButton" name="button_2" base="EditButton">
<events>
<handler event="EVT_BUTTON">OnOpStart</handler>
</events>
<label>Start</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxButton" name="button_3" base="EditButton">
<events>
<handler event="EVT_BUTTON">OnOpStop</handler>
</events>
<label>Stop</label>
</object>
</object>
</object>
</object>
<object class="sizeritem">
<option>1</option>
<border>0</border>
<flag>wxEXPAND</flag>
<object class="wxStaticBoxSizer" name="sizer_9" base="EditStaticBoxSizer">
<orient>wxHORIZONTAL</orient>
<label>AC1 Port</label>
<object class="sizeritem">
<option>1</option>
<border>0</border>
<flag>wxEXPAND</flag>
<object class="wxGridSizer" name="grid_sizer_3" base="EditGridSizer">
<rows>3</rows>
<cols>2</cols>
<vgap>0</vgap>
<hgap>0</hgap>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxStaticText" name="label_8" base="EditStaticText">
<label>Control Method</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxChoice" name="choice_ac1_control" base="EditChoice">
<selection>0</selection>
<choices>
<choice>IDLE</choice>
<choice>NET</choice>
<choice>GPWR</choice>
<choice>FPWR</choice>
</choices>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxStaticText" name="label_11" base="EditStaticText">
<label>Real Power Setpoint</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxTextCtrl" name="text_ctrl_ac1_realpwr" base="EditTextCtrl">
<value>0</value>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxStaticText" name="label_12" base="EditStaticText">
<label>Reactive Power Setpoint</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxTextCtrl" name="text_ctrl_ac1_reactpwr" base="EditTextCtrl">
<value>0</value>
</object>
</object>
</object>
</object>
</object>
</object>
<object class="sizeritem">
<option>1</option>
<border>0</border>
<flag>wxEXPAND</flag>
<object class="wxStaticBoxSizer" name="sizer_10" base="EditStaticBoxSizer">
<orient>wxHORIZONTAL</orient>
<label>DC2 Port</label>
<object class="sizeritem">
<option>1</option>
<border>0</border>
<flag>wxEXPAND</flag>
<object class="wxGridSizer" name="grid_sizer_1" base="EditGridSizer">
<rows>7</rows>
<cols>2</cols>
<vgap>0</vgap>
<hgap>0</hgap>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxStaticText" name="label_9" base="EditStaticText">
<label>Contol Method</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxChoice" name="choice_dc2_control" base="EditChoice">
<selection>0</selection>
<choices>
<choice>IDLE</choice>
<choice>NET</choice>
<choice>PV/MPPT</choice>
<choice>CURR</choice>
<choice>PWR</choice>
<choice>VOLT</choice>
</choices>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxStaticText" name="label_19" base="EditStaticText">
<label>Current Setpoint</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxTextCtrl" name="text_ctrl_dc2_current" base="EditTextCtrl">
<value>0</value>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxStaticText" name="label_13" base="EditStaticText">
<label>Power Setpoint</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxTextCtrl" name="text_ctrl_dc2_power" base="EditTextCtrl">
<value>0</value>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxStaticText" name="label_14" base="EditStaticText">
<label>Voltage Setpoint</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxTextCtrl" name="text_ctrl_dc2_voltage" base="EditTextCtrl">
<value>0</value>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxStaticText" name="label_17" base="EditStaticText">
<label>Precharge Limit Low</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxStaticText" name="label_18" base="EditStaticText">
<label>Precharge Limit High</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxTextCtrl" name="text_ctrl_7" base="EditTextCtrl">
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxTextCtrl" name="text_ctrl_8" base="EditTextCtrl">
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxButton" name="button_4" base="EditButton">
<label>Enable Precharge</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxButton" name="button_5" base="EditButton">
<label>Disable Precharge</label>
</object>
</object>
</object>
</object>
</object>
</object>
<object class="sizeritem">
<option>1</option>
<border>0</border>
<flag>wxEXPAND</flag>
<object class="wxStaticBoxSizer" name="sizer_11" base="EditStaticBoxSizer">
<orient>wxHORIZONTAL</orient>
<label>DC3 Port</label>
<object class="sizeritem">
<option>1</option>
<border>1</border>
<flag>wxALL|wxEXPAND</flag>
<object class="wxGridSizer" name="grid_sizer_2" base="EditGridSizer">
<rows>4</rows>
<cols>2</cols>
<vgap>0</vgap>
<hgap>0</hgap>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxStaticText" name="label_10" base="EditStaticText">
<label>Control Method</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxChoice" name="choice_dc3_control" base="EditChoice">
<selection>0</selection>
<choices>
<choice>IDLE</choice>
<choice>NET</choice>
<choice>PV/MPPT</choice>
<choice>CURR</choice>
<choice>PWR</choice>
<choice>VOLT</choice>
</choices>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxStaticText" name="label_20" base="EditStaticText">
<label>Current Setpoint</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxTextCtrl" name="text_ctrl_dc3_current" base="EditTextCtrl">
<value>0</value>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxStaticText" name="label_15" base="EditStaticText">
<label>Power Setpoint</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxTextCtrl" name="text_ctrl_dc3_power" base="EditTextCtrl">
<value>0</value>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxStaticText" name="label_16" base="EditStaticText">
<label>Voltage Setpoint</label>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<object class="wxTextCtrl" name="text_ctrl_dc3_voltage" base="EditTextCtrl">
<value>0</value>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
<object class="sizeritem">
<option>1</option>
<border>0</border>
<flag>wxEXPAND</flag>
<object class="wxPropertyGridManager" name="property_grid_1" base="EditPropertyGridManager">
<extracode_post>self.property_grid_1.ShowHeader()</extracode_post>
<style>wxPG_TOOLBAR|wxPG_DESCRIPTION</style>
</object>
</object>
</object> </object>
</object> </object>
</application> </application>

View file

@ -1,6 +1,10 @@
import easymodbus.modbusClient import easymodbus.modbusClient
from datetime import datetime as dt from datetime import datetime as dt
from functools import reduce from functools import reduce
from registers import regdict
import numpy as np
from pubsub import pub
nRegsPortStatus = 32 nRegsPortStatus = 32
@ -20,6 +24,27 @@ addrStatusThermal = 0x0160
addrStatusDiagnostic = 0x0180 addrStatusDiagnostic = 0x0180
system_status = ["" for i in range(16)]
system_status[0] = "PCS in self-test mode"
system_status[1] = "PCS reconnect timer 0 counting down from last disconnect due to ABORT-0 fault"
system_status[2] = "PCS reconnect timer 1 counting down from last disconnect due to ABORT-1 fault"
system_status[3] = "PCS reconnect timer 2 counting down from last disconnect due to ABORT-2 fault"
system_status[4] = "PCS DC2 port pre-charge operation is active"
system_status[5] = "Invalid control method programmed in PCS"
system_status[6] = "AC rotation indication ( 0 AC1 port wired as A-B-C | 1 AC1 port wired as C-B-A )"
system_status[7] = "PV/MPPT low-voltage indication ( 0 PV/MPPT is disabled due to low voltage at port | 1 PV/MPPT " \
"is enabled with voltage above minimum PV/MPPT limit set for port ) "
system_status[8] = "PV/MPPT time-of-day indication ( 0 System time-of-day outside PV/MPPT operational range | 1 " \
"System time-of-day satisfies start-time and stop-time limits set for PV/MPPT port, PV/MPPT port " \
"allowed to convert power ) "
system_status[9] = "PCS power conversion is active"
system_status[10] = "PCS hardware shutdown function is active (power conversion disabled)"
system_status[11] = "PCS lockdown active due to GFDI fault, IMI fault, or fan fault"
system_status[12] = "PCS fault of severity level ABORT-0 active"
system_status[13] = "PCS fault of severity level ABORT-1 active"
system_status[14] = "PCS fault of severity level ABORT-2 active"
system_status[15] = "PCS GFDI fault or IMI fault detected"
p1_port_status = {0: "AC1 port is real power soft-limiting", p1_port_status = {0: "AC1 port is real power soft-limiting",
1: "AC1 port is current soft-limiting", 1: "AC1 port is current soft-limiting",
2: "AC1 port is reactive power soft-limiting", 2: "AC1 port is reactive power soft-limiting",
@ -29,8 +54,12 @@ p1_port_status = {0: "AC1 port is real power soft-limiting",
6: "Reserved", 6: "Reserved",
7: "AC1 port is throttling back on port DC3 due to soft-limiting", 7: "AC1 port is throttling back on port DC3 due to soft-limiting",
8: "AC1 port has the seamless transfer feature enabled when in FPWR control", 8: "AC1 port has the seamless transfer feature enabled when in FPWR control",
9: "The PCS SEL-547 interface transfer switch HW is indicating the PCS is islanded (islanding contactor is commanded to open). If enabled, the PCS is able to form a microgrid in FPWR control.", 9: "The PCS SEL-547 interface transfer switch HW is indicating the PCS is islanded (islanding "
10: "The PCS SEL-547 interface transfer switch HW is indicating the PCS is islanded (islanding contactor has successfully opened). If enabled, the PCS is able to form a microgrid in FPWR control.", "contactor is commanded to open). If enabled, the PCS is able to form a microgrid in FPWR "
"control.",
10: "The PCS SEL-547 interface transfer switch HW is indicating the PCS is islanded (islanding "
"contactor has successfully opened). If enabled, the PCS is able to form a microgrid in FPWR "
"control.",
11: "Reserved", 11: "Reserved",
12: "Reserved", 12: "Reserved",
13: "Reserved", 13: "Reserved",
@ -71,30 +100,40 @@ p3_port_status = {0: "DC3 port is power soft-limiting",
14: "Reserved", 14: "Reserved",
15: "Reserved"} 15: "Reserved"}
mode_dict = {
"IDLE": 0x0000,
"NET": 0x0001,
"GPWR": 0x0402,
"FPWR": 0x0502,
"PV/MPPT": 0x0002,
"CURR": 0x0301,
"PWR": 0x0401,
"VOLT": 0x0501,
}
def toPower(x): def toPower(x):
return x * 10 return np.int16(x) * 10
def toVar(x): def toVar(x):
return x * 10 return np.int16(x) * 10
def toVa(x): def toVa(x):
return x * 10 return np.int16(x) * 10
def toPwrFactor(x): def toPwrFactor(x):
return x * 0.01 return np.int16(x) * 0.01
def toCurrent(x): def toCurrent(x):
return x * 0.1 return np.int16(x) * 0.1
def toVoltage(x): def toVoltage(x):
return x return np.int16(x)
def toFreq(x): def toFreq(x):
return x * 0.001 return np.uint16(x) * 0.001
def toTemperature(x): def toTemperature(x):
return x * 0.1 return np.uint16(x) * 0.1
def toRpm(x): def toRpm(x):
return x return x
@ -139,11 +178,27 @@ def parse_address (addr_string):
return int(start, 16), nregisters return int(start, 16), nregisters
valueConversion = {"U16": np.uint16,
"S16": np.int16,
"HEX4": toBitString,
"HEX": toBitString,
"POWER": toPower,
"VAR": toVar,
"VA": toVa,
"PF": toPwrFactor,
"CURRENT": toCurrent,
"VOLTAGE": toVoltage,
"FREQ": toFreq,
"TEMP": toTemperature,
"RPM": toRpm,
"MINUTES": toMinutes,
"BAUD": toBaud,
"STRING": toString, }
class StabilitiRegister(object): class StabilitiRegister(object):
def __init__(self, name, proplist): def __init__(self, name, proplist):
self.name = name self.name = name
self.index = proplist[0] self.index = list(map(int, proplist[0]))
self.address, self.size = parse_address(proplist[1]) self.address, self.size = parse_address(proplist[1])
self.access = proplist[2] self.access = proplist[2]
self.dtype = proplist[3] self.dtype = proplist[3]
@ -159,8 +214,11 @@ class StabilitiRegister(object):
def is_writable(self): def is_writable(self):
return 'W' in self.access return 'W' in self.access
def convertValue(self, raw):
return valueConversion[self.dtype](raw)
def getdefaultvalue(self): def getdefaultvalue(self):
if self.vdefault = 'NA': if self.vdefault == 'NA':
return None return None
else: else:
return self.vdefault return self.vdefault
@ -170,7 +228,8 @@ class StabilitiController(object):
def __init__(self, ipaddr, port=502, uid=240): def __init__(self, ipaddr, port=502, uid=240):
self.client = easymodbus.modbusClient.ModbusClient(ipaddr, port) self.client = easymodbus.modbusClient.ModbusClient(ipaddr, port)
self.client.unitidentifier = uid self.client.unitidentifier = uid
self.reg_info = {} self.reg_info = {k:StabilitiRegister(k, v) for k, v in regdict.items()}
self.registers = np.zeros(4000, dtype=np.int)
def checkConnect(self): def checkConnect(self):
if not self.client.is_connected(): if not self.client.is_connected():
@ -180,6 +239,39 @@ class StabilitiController(object):
if self.client.is_connected(): if self.client.is_connected():
self.client.close() self.client.close()
def setPortModes(self, modes):
self.client.write_single_register(self.reg_info["p1_control_method"].address, mode_dict[modes[0]])
self.client.write_single_register(self.reg_info["p2_control_method"].address, mode_dict[modes[1]])
self.client.write_single_register(self.reg_info["p3_control_method"].address, mode_dict[modes[2]])
def setPortSetpoints(self, val):
for k,v in val.items():
self.client.write_single_register(self.reg_info[k].address, int(float(v)))
def setUserStart(self):
self.client.write_single_register(self.reg_info["user_start"].address, 1)
def setUserStop(self):
self.client.write_single_register(self.reg_info["user_stop"].address, 1)
def readAllRegisters(self):
print("read all registers")
self.checkConnect()
message_size = 64
for i in range(0, 654, message_size):
holdingRegisters = self.client.read_holdingregisters(i,message_size)
self.registers[i:i+message_size] = np.asarray(holdingRegisters)
for i in range(2000, 2069, message_size):
holdingRegisters = self.client.read_holdingregisters(i,message_size)
self.registers[i:i+message_size] = np.asarray(holdingRegisters)
pub.sendMessage("read_all_registers", reg=self.registers, info=self.reg_info)
def reg2str(self, r): def reg2str(self, r):
return toString(r) return toString(r)
@ -291,26 +383,18 @@ b3-b4: The status of the fault.
def getSystemStatus(self): def getSystemStatus(self):
'''Get PCS Status''' '''Get PCS Status'''
'''\ regs = self.registers
system_status[0] PCS in self-test mode
system_status[1] PCS reconnect timer 0 counting down from last disconnect due to ABORT-0 fault sys_dict = {k:v for k,v in self.reg_info.items() if v.index[0] == 4 and v.index[1] == 10}
system_status[2] PCS reconnect timer 1 counting down from last disconnect due to ABORT-1 fault
system_status[3] PCS reconnect timer 2 counting down from last disconnect due to ABORT-2 fault system_all_status = {
system_status[4] PCS DC2 port pre-charge operation is active k: v.convertValue(regs[v.address]) for k, v in sys_dict.items()
system_status[5] Invalid control method programmed in PCS }
system_status[6] AC rotation indication ( 0 AC1 port wired as A-B-C | 1 AC1 port wired as C-B-A )
system_status[7] PV/MPPT low-voltage indication ( 0 PV/MPPT is disabled due to low voltage at port | 1 PV/MPPT is enabled with voltage above minimum PV/MPPT limit set for port ) status = system_all_status['system_status']
system_status[8] PV/MPPT time-of-day indication ( 0 System time-of-day outside PV/MPPT operational range | 1 System time-of-day satisfies start-time and stop-time limits set for PV/MPPT port, PV/MPPT port allowed to convert power )
system_status[9] PCS power conversion is active return selectMessages(status, system_status), system_all_status
system_status[10] PCS hardware shutdown function is active (power conversion disabled)
system_status[11] PCS lockdown active due to GFDI fault, IMI fault, or fan fault
system_status[12] PCS fault of severity level ABORT-0 active
system_status[13] PCS fault of severity level ABORT-1 active
system_status[14] PCS fault of severity level ABORT-2 active
system_status[15] PCS GFDI fault or IMI fault detected
'''
regs = self.client.read_holdingregisters(addrStatusSystem, nRegsPortStatus)
pass
def getPortStatusAC1(self): def getPortStatusAC1(self):
'''Get Status of AC1 Power Port''' '''Get Status of AC1 Power Port'''
@ -318,7 +402,8 @@ system_status[15] PCS GFDI fault or IMI fault detected
def relAddr(x): def relAddr(x):
return x - addrStatusAC1 return x - addrStatusAC1
regs = self.client.read_holdingregisters(addrStatusAC1, nRegsPortStatus) # regs = self.client.read_holdingregisters(addrStatusAC1, nRegsPortStatus)
regs = self.registers[addrStatusAC1:addrStatusAC1+nRegsPortStatus]
p1_all_status = {"p1_port_status": toBitString(regs[relAddr(96)]), p1_all_status = {"p1_port_status": toBitString(regs[relAddr(96)]),
"p1_real_pwr_ramped": toPower(regs[relAddr(100)]), "p1_real_pwr_ramped": toPower(regs[relAddr(100)]),
@ -351,7 +436,8 @@ system_status[15] PCS GFDI fault or IMI fault detected
def relAddr(x): def relAddr(x):
return x - addrStatusDC2 return x - addrStatusDC2
regs = self.client.read_holdingregisters(addrStatusDC2, nRegsPortStatus) # regs = self.client.read_holdingregisters(addrStatusDC2, nRegsPortStatus)
regs = self.registers[addrStatusDC2:addrStatusDC2+nRegsPortStatus]
p2_all_status = {'p2_port_status': toBitString(regs[relAddr(160)]), p2_all_status = {'p2_port_status': toBitString(regs[relAddr(160)]),
'p2_current_ramped': toCurrent(regs[relAddr(164)]), 'p2_current_ramped': toCurrent(regs[relAddr(164)]),
@ -375,7 +461,11 @@ system_status[15] PCS GFDI fault or IMI fault detected
def relAddr(x): def relAddr(x):
return x - addrStatusDC3 return x - addrStatusDC3
regs = self.client.read_holdingregisters(addrStatusDC3, nRegsPortStatus) regs = self.registers[addrStatusDC3:addrStatusDC3+nRegsPortStatus]
# regs = self.client.read_holdingregisters(addrStatusDC3, nRegsPortStatus)
# self.registers[addrStatusDC3, nRegsPortStatus] = regs
p3_all_status = {'p3_port_status': toBitString(regs[relAddr(224)]), p3_all_status = {'p3_port_status': toBitString(regs[relAddr(224)]),
'p3_current_ramped': toCurrent(regs[relAddr(228)]), 'p3_current_ramped': toCurrent(regs[relAddr(228)]),
@ -390,4 +480,3 @@ system_status[15] PCS GFDI fault or IMI fault detected
status = p3_all_status['p3_port_status'] status = p3_all_status['p3_port_status']
return selectMessages(status, p3_port_status), p3_all_status return selectMessages(status, p3_port_status), p3_all_status