From 8481b607c5d74303d52ffa4311bb8e7ad612f892 Mon Sep 17 00:00:00 2001 From: Yeongdo Park Date: Mon, 10 Aug 2020 16:55:22 -0700 Subject: [PATCH] WebRelay responsible for Modbus and minimal skeleton code for CAN --- FaultMonitor.py | 131 ++++++------------------------------------------ WebRelay.py | 66 ++++++++++++++++++++++++ c2m.py | 38 ++++++++++++++ can.conf | 4 ++ 4 files changed, 122 insertions(+), 117 deletions(-) create mode 100644 WebRelay.py create mode 100644 c2m.py create mode 100644 can.conf diff --git a/FaultMonitor.py b/FaultMonitor.py index 4301f86..fd4ecdc 100644 --- a/FaultMonitor.py +++ b/FaultMonitor.py @@ -12,27 +12,17 @@ import gettext import re import sys -import pprint from pubsub import pub import pubsub.utils.notification -import easymodbus.modbusClient -from registers import regdict - -from stabiliti import StabilitiController as SC -from faults import faultInfo +from WebRelay import WebRelay from FaultView import FaultFrame print('pubsub API version', pub.VERSION_API) pubsub.utils.notification.useNotifyByWriteFile(sys.stdout) -class WebRelay: - def __init__(self, n_relay=10): - self.n_relay = n_relay - self.relay_status = [False for i in range(self.n_relay)] - class Controller: def __init__(self, view): self.sc = None @@ -42,96 +32,31 @@ class Controller: self.refresh_rate = 2000 self.mode = False - self.mbclient = None + self.model = WebRelay() pub.subscribe(self.startTimer, 'monitoring_started') pub.subscribe(self.stopTimer, 'monitoring_stopped') - pub.subscribe(self.applyNetworkConfigs, 'apply_network_configs') - pub.subscribe(self.resetNetworkConfigs, 'reset_network_configs') - pub.subscribe(self.resetPcsRemote, 'reset_pcs_remote') - pub.subscribe(self.checkSysOpMode, 'check_system_op_mode') - pub.subscribe(self.startSystemOp, "start_system_op_manual") - pub.subscribe(self.stopSystemOp, "stop_system_op_manual") + pub.subscribe(self.model.apply_network_configs, 'apply_network_configs') - pub.subscribe(self.turnRelayOn, "turn_relay_on") - pub.subscribe(self.turnRelayOff, "turn_relay_off") - - ''' -def WriteSingleCoil(self, startingAddress, value) - -Write single Coil to Server device (Function code 5) -startingAddress: Coil to be written -value: Coil Value to be written - -def WriteMultipleCoils(self, startingAddress, values) - -Write multiple coils to Server device (Function code 15) -startingAddress : First coil to be written -values: Coil Values [0..quantity-1] to be written - ''' - - def turnRelayOn(self, relay_id): - ''' - :param relay_id: id of relay to turn on - :return: None - ''' - self.mbclient.write_single_coil(relay_id-1, True) - - def turnRelayOff(self, relay_id): - ''' - :param relay_id: id of relay to turn off - :return: None - ''' - self.mbclient.write_single_coil(relay_id-11, False) - - - def startSystemOp(self, mode, val): - self.sc.setPortModes(mode) - self.sc.setPortSetpoints(val) - self.sc.setUserStart() - - def stopSystemOp(self): - self.sc.setUserStop() + pub.subscribe(self.model.turn_relay_on, "turn_relay_on") + pub.subscribe(self.model.turn_relay_off, "turn_relay_off") def startTimer(self): - self.mbclient.connect() + self.model.connect_slave() self.timer.Start(self.refresh_rate) def stopTimer(self): - self.mbclient.close() + self.model.disconnect_slave() self.timer.Stop() - def applyNetworkConfigs(self, ncDict): - if self.mbclient: - if self.mbclient.is_connected(): - self.mbclient.close() - self.mbclient = easymodbus.modbusClient.ModbusClient(ncDict["ipaddr"], ncDict["port"]) - self.mbclient.unitidentifier = ncDict["uid"] - self.refresh_rate = ncDict.pop("refresh") - - def resetNetworkConfigs(self): - if self.mbclient: - if self.mbclient.is_connected(): - self.mbclient.close() - self.mbclient = None - - def resetPcsRemote(self): - if self.sc: - self.sc.resetPcs() - - def checkSysOpMode(self): - if self.sc: - self.mode = self.sc.checkOpMode() - a = "Auto" if self.mode else "Manual" - self.view.text_op_mode.SetValue(a) - def OnTimer(self, event): # Read registers - relay_status = self.mbclient.read_coils(0,10) + relay_status = self.model.client.read_coils(0,10) # Process registers # Show Registers for i, rstatus in enumerate(relay_status): + self.model.relay_status[i] = rstatus if rstatus: self.view.indicators[i].SetValue("ON") self.view.indicators[i].SetBackgroundColour(wx.Colour(0, 255, 0)) @@ -175,23 +100,6 @@ class MyFrame(FaultFrame): 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. - pub.sendMessage("fault_selected", pos=(event.GetRow(), event.GetCol())) - event.Skip() - - def SetFaultGrid(self, fActivity, fOccurence): - if len(fActivity) == len(fOccurence) == 64: - for i in range(8): - for j in range(8): - if fActivity[i * 8 + j] == '1': - self.fault_grid.SetCellBackgroundColour(i, j, wx.LIGHT_GREY) - else: - self.fault_grid.SetCellBackgroundColour(i, j, wx.WHITE) - if fOccurence[i * 8 + j] == '1': - self.fault_grid.SetCellValue(i, j, "O") - else: - self.fault_grid.SetCellValue(i, j, "") - def ToggleMonitoring(self, event): # wxGlade: MyFrame. btnLabel = self.button_1.GetLabel() if self.button_1.Value: @@ -211,14 +119,14 @@ class MyFrame(FaultFrame): self.input_ip.Disable() self.input_refresh.Disable() - ncDict = { + nc_dict = { "ipaddr": self.input_ip.GetValue(), "port": int(self.input_port.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", nc_dict=nc_dict) self.button_1.Enable() @@ -227,10 +135,7 @@ class MyFrame(FaultFrame): if not self.button_1.Enabled: return - pub.sendMessage("reset_network_configs") self.button_1.SetValue(False) - self.ToggleMonitoring(None) - self.button_1.Disable() self.input_uid.Enable() @@ -238,19 +143,12 @@ class MyFrame(FaultFrame): self.input_ip.Enable() self.input_refresh.Enable() - def OnButtonRemoteReset(self, event): - pub.sendMessage("reset_pcs_remote") - self.OnReset() - - def OnCheckSysOpMode(self, event): - pub.sendMessage("check_system_op_mode") - def OnRelayOn(self, event): - pub.sendMessage("turn_relay_on", relay_id = event.GetId()) + pub.sendMessage("turn_relay_on", relay_id = event.GetId()-1) event.Skip() def OnRelayOff(self, event): - pub.sendMessage("turn_relay_off", relay_id = event.GetId()) + pub.sendMessage("turn_relay_off", relay_id = event.GetId()-11) event.Skip() def OnRelayPulse(self, event): @@ -276,5 +174,4 @@ if __name__ == "__main__": app = MyApp(0) app.MainLoop() - if app.c.sc: - app.c.sc.checkClose() + app.c.model.disconnect_slave() diff --git a/WebRelay.py b/WebRelay.py new file mode 100644 index 0000000..cb0dfac --- /dev/null +++ b/WebRelay.py @@ -0,0 +1,66 @@ +import easymodbus.modbusClient + + +class WebRelay: + def __init__(self, n_relay=10): + self.n_relay = n_relay + self.relay_status = [False for i in range(self.n_relay)] + self.client = None + + def __del__(self): + if self.client: + if self.client.is_connected(): + self.client.close() + + def apply_network_configs(self, nc_dict): + self.ip_address = nc_dict["ipaddr"] + self.port = nc_dict["port"] + self.uid = nc_dict["uid"] + + def connect_slave(self): + if not self.client: + self.client = easymodbus.modbusClient.ModbusClient(self.ip_address, self.port) + self.client.unitidentifier = self.uid + self.client.connect() + else: + if not self.client.is_connected(): + self.client = None + self.connect_slave() + + def disconnect_slave(self): + if self.client: + self.client.close() + self.client = None + + ''' +def WriteSingleCoil(self, startingAddress, value) + +Write single Coil to Server device (Function code 5) +startingAddress: Coil to be written +value: Coil Value to be written + +def WriteMultipleCoils(self, startingAddress, values) + +Write multiple coils to Server device (Function code 15) +startingAddress : First coil to be written +values: Coil Values [0..quantity-1] to be written + ''' + + def turn_relay_on(self, relay_id): + ''' + :param relay_id: id of relay to turn on + :return: None + ''' + self.check_write_single_coil(relay_id, True) + + def turn_relay_off(self, relay_id): + ''' + :param relay_id: id of relay to turn off + :return: None + ''' + self.check_write_single_coil(relay_id, False) + + def check_write_single_coil(self, relay_id, value): + if self.client: + if self.client.is_connected(): + self.client.write_single_coil(relay_id, value) \ No newline at end of file diff --git a/c2m.py b/c2m.py new file mode 100644 index 0000000..fb68de2 --- /dev/null +++ b/c2m.py @@ -0,0 +1,38 @@ +import can +import cantools + +from WebRelay import WebRelay + +class Model: + def __init__(self): + self.bus = None + self.notifier = None + self.listen_bms = can.Printer() + #self.listen_bms = BmsListener(self) + + def start_can(self): + self.bus = can.Bus() + self.notifier = can.Notifier(self.bus, [self.listen_bms]) + + def stop_can(self): + self.notifier.stop() + self.bus.shutdown() + self.notifier = None + self.bus = None + + def process_message(self, msg): + pass + + +if __name__ == "__main__": + nc_dict = dict() + nc_dict["ipaddr"] = "192.168.1.2" + nc_dict["port"] = 502 + nc_dict["uid"] = 240 + + modbus = WebRelay() + modbus.apply_network_configs(nc_dict) + + canbus = Model() + + canbus.start_can() diff --git a/can.conf b/can.conf new file mode 100644 index 0000000..4e4c39a --- /dev/null +++ b/can.conf @@ -0,0 +1,4 @@ +[default] +interface = socketcan +channel = can0 +bitrate = 250000 \ No newline at end of file