﻿from TSMaster import *

# Auto Generated Python Code, do not modify START [UI] --------------
class Raw_CAN_Transmit(frmTSForm):
    def __init__(self):
        # set type name internally
        self.ExternalTypeName = type(self).__name__
        try:
            # Form properties
            if not self.IsConfigurationLoaded:
                self.Left = 43
                self.Top = 54
                self.Caption = 'Raw_CAN_Transmit'
                self.ClientHeight = 502
                self.ClientWidth = 786
            self.Color = clBtnFace
            self.DoubleBuffered = True
            self.Font.Charset = DEFAULT_CHARSET
            self.Font.Color = clWindowText
            self.Font.Height = -12
            self.Font.Name = 'Segoe UI'
            self.Font.Style = []
            self.KeyPreview = True
            self.Position = "poDesigned"
            self.Visible = True
            self.TextHeight = 15
            # Create control: grpConf = GroupBox(self)
            self.grpConf = GroupBox(self)
            self.grpConf.Name = "grpConf"
            self.grpConf.Parent = self
            self.grpConf.Left = 8
            self.grpConf.Top = 56
            self.grpConf.Width = 768
            self.grpConf.Height = 304
            self.grpConf.Cursor = crArrow
            self.grpConf.Anchors = ["akLeft", "akTop", "akRight", "akBottom"]
            self.grpConf.Caption = 'Raw CAN Message Configuration'
            self.grpConf.TabOrder = 0
            # Create control: lblDLC = Label(self)
            self.lblDLC = Label(self)
            self.lblDLC.Name = "lblDLC"
            self.lblDLC.Parent = self.grpConf
            self.lblDLC.Left = 189
            self.lblDLC.Top = 35
            self.lblDLC.Width = 25
            self.lblDLC.Height = 15
            self.lblDLC.Cursor = crArrow
            self.lblDLC.Caption = 'DLC:'
            # Create control: lblType = Label(self)
            self.lblType = Label(self)
            self.lblType.Name = "lblType"
            self.lblType.Parent = self.grpConf
            self.lblType.Left = 289
            self.lblType.Top = 35
            self.lblType.Width = 27
            self.lblType.Height = 15
            self.lblType.Cursor = crArrow
            self.lblType.Caption = 'Type:'
            # Create control: lblChannel = Label(self)
            self.lblChannel = Label(self)
            self.lblChannel.Name = "lblChannel"
            self.lblChannel.Parent = self.grpConf
            self.lblChannel.Left = 503
            self.lblChannel.Top = 35
            self.lblChannel.Width = 47
            self.lblChannel.Height = 15
            self.lblChannel.Cursor = crArrow
            self.lblChannel.Anchors = ["akTop", "akRight"]
            self.lblChannel.Caption = 'Channel:'
            # Create control: Label4 = Label(self)
            self.Label4 = Label(self)
            self.Label4.Name = "Label4"
            self.Label4.Parent = self.grpConf
            self.Label4.Left = 16
            self.Label4.Top = 72
            self.Label4.Width = 58
            self.Label4.Height = 15
            self.Label4.Cursor = crArrow
            self.Label4.Caption = 'Data Bytes:'
            # Create control: edtId = LabeledEdit(self)
            self.edtId = LabeledEdit(self)
            self.edtId.Name = "edtId"
            self.edtId.Parent = self.grpConf
            self.edtId.Left = 80
            self.edtId.Top = 32
            self.edtId.Width = 88
            self.edtId.Height = 23
            self.edtId.Cursor = crArrow
            self.edtId.Alignment = "taCenter"
            self.edtId.EditLabel.Width = 50
            self.edtId.EditLabel.Height = 23
            self.edtId.EditLabel.Caption = 'Identifier:'
            self.edtId.LabelPosition = "lpLeft"
            self.edtId.LabelSpacing = 12
            self.edtId.TabOrder = 0
            self.edtId.Text = '0x123'
            # Create control: cbDLC = ComboBox(self)
            self.cbDLC = ComboBox(self)
            self.cbDLC.Name = "cbDLC"
            self.cbDLC.Parent = self.grpConf
            self.cbDLC.Left = 224
            self.cbDLC.Top = 32
            self.cbDLC.Width = 45
            self.cbDLC.Height = 23
            self.cbDLC.Cursor = crArrow
            self.cbDLC.Style = "csDropDownList"
            self.cbDLC.ItemIndex = 8
            self.cbDLC.TabOrder = 1
            self.cbDLC.Text = '8'
            self.cbDLC.Items.Assign(['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15'])
            # Create control: cbType = ComboBox(self)
            self.cbType = ComboBox(self)
            self.cbType.Name = "cbType"
            self.cbType.Parent = self.grpConf
            self.cbType.Left = 328
            self.cbType.Top = 32
            self.cbType.Width = 152
            self.cbType.Height = 23
            self.cbType.Cursor = crArrow
            self.cbType.Style = "csDropDownList"
            self.cbType.Anchors = ["akLeft", "akTop", "akRight"]
            self.cbType.ItemIndex = 0
            self.cbType.TabOrder = 2
            self.cbType.Text = 'Standard Data Frame'
            self.cbType.Items.Assign(['Standard Data Frame','Standard Remote Frame','Standard FD Frame','Extended Data Frame','Extended Remote Frame','Extended FD Frame'])
            # Create control: cbChannel = ComboBox(self)
            self.cbChannel = ComboBox(self)
            self.cbChannel.Name = "cbChannel"
            self.cbChannel.Parent = self.grpConf
            self.cbChannel.Left = 568
            self.cbChannel.Top = 32
            self.cbChannel.Width = 61
            self.cbChannel.Height = 23
            self.cbChannel.Cursor = crArrow
            self.cbChannel.Style = "csDropDownList"
            self.cbChannel.Anchors = ["akTop", "akRight"]
            self.cbChannel.TabOrder = 3
            # Create control: grd = StringGrid(self)
            self.grd = StringGrid(self)
            self.grd.Name = "grd"
            self.grd.Parent = self.grpConf
            self.grd.Left = 80
            self.grd.Top = 72
            self.grd.Width = 664
            self.grd.Height = 216
            self.grd.Cursor = crArrow
            self.grd.Anchors = ["akLeft", "akTop", "akRight", "akBottom"]
            self.grd.ColCount = 9
            self.grd.DefaultColAlignment = "taCenter"
            self.grd.DefaultRowHeight = 21
            self.grd.FixedColor = clActiveCaption
            self.grd.RowCount = 9
            self.grd.Options = ["goFixedVertLine", "goFixedHorzLine", "goVertLine", "goHorzLine", "goRangeSelect", "goEditing", "goFixedRowDefAlign"]
            self.grd.TabOrder = 4
            # Create control: chkHex = CheckBox(self)
            self.chkHex = CheckBox(self)
            self.chkHex.Name = "chkHex"
            self.chkHex.Parent = self.grpConf
            self.chkHex.Left = 645
            self.chkHex.Top = 35
            self.chkHex.Width = 105
            self.chkHex.Height = 17
            self.chkHex.Cursor = crArrow
            self.chkHex.Anchors = ["akTop", "akRight"]
            self.chkHex.Caption = 'Hex Edit Mode'
            self.chkHex.Checked = True
            self.chkHex.State = "cbChecked"
            self.chkHex.TabOrder = 5
            # Create control: GroupBox2 = GroupBox(self)
            self.GroupBox2 = GroupBox(self)
            self.GroupBox2.Name = "GroupBox2"
            self.GroupBox2.Parent = self
            self.GroupBox2.Left = 8
            self.GroupBox2.Top = 368
            self.GroupBox2.Width = 768
            self.GroupBox2.Height = 105
            self.GroupBox2.Cursor = crArrow
            self.GroupBox2.Anchors = ["akLeft", "akRight", "akBottom"]
            self.GroupBox2.Caption = 'Frame Trigger'
            self.GroupBox2.TabOrder = 1
            # Create control: btnTx = TSBitBtn(self)
            self.btnTx = TSBitBtn(self)
            self.btnTx.Name = "btnTx"
            self.btnTx.Parent = self.GroupBox2
            self.btnTx.Left = 80
            self.btnTx.Top = 24
            self.btnTx.Width = 208
            self.btnTx.Height = 25
            self.btnTx.Cursor = crArrow
            self.btnTx.Caption = 'Click to Transmit'
            self.btnTx.Kind = "bkOK"
            self.btnTx.NumGlyphs = 2
            self.btnTx.TabOrder = 0
            # Create control: chkCyclic = CheckBox(self)
            self.chkCyclic = CheckBox(self)
            self.chkCyclic.Name = "chkCyclic"
            self.chkCyclic.Parent = self.GroupBox2
            self.chkCyclic.Left = 320
            self.chkCyclic.Top = 27
            self.chkCyclic.Width = 160
            self.chkCyclic.Height = 17
            self.chkCyclic.Cursor = crArrow
            self.chkCyclic.Caption = 'Cyclic Transmission (ms)'
            self.chkCyclic.TabOrder = 1
            # Create control: cbCyclic = ComboBox(self)
            self.cbCyclic = ComboBox(self)
            self.cbCyclic.Name = "cbCyclic"
            self.cbCyclic.Parent = self.GroupBox2
            self.cbCyclic.Left = 496
            self.cbCyclic.Top = 25
            self.cbCyclic.Width = 121
            self.cbCyclic.Height = 23
            self.cbCyclic.Cursor = crArrow
            self.cbCyclic.TabOrder = 2
            self.cbCyclic.Text = '100'
            self.cbCyclic.Items.Assign(['20','50','100','500','1000'])
            # Create control: chkOnMsg = CheckBox(self)
            self.chkOnMsg = CheckBox(self)
            self.chkOnMsg.Name = "chkOnMsg"
            self.chkOnMsg.Parent = self.GroupBox2
            self.chkOnMsg.Left = 320
            self.chkOnMsg.Top = 64
            self.chkOnMsg.Width = 170
            self.chkOnMsg.Height = 17
            self.chkOnMsg.Cursor = crArrow
            self.chkOnMsg.Caption = 'On Message Transmission'
            self.chkOnMsg.TabOrder = 3
            # Create control: edtOnMsg = Edit(self)
            self.edtOnMsg = Edit(self)
            self.edtOnMsg.Name = "edtOnMsg"
            self.edtOnMsg.Parent = self.GroupBox2
            self.edtOnMsg.Left = 496
            self.edtOnMsg.Top = 64
            self.edtOnMsg.Width = 121
            self.edtOnMsg.Height = 23
            self.edtOnMsg.Cursor = crArrow
            self.edtOnMsg.Alignment = "taCenter"
            self.edtOnMsg.TabOrder = 4
            self.edtOnMsg.Text = '0x100'
            # Create control: aiCyclic = ActivityIndicator(self)
            self.aiCyclic = ActivityIndicator(self)
            self.aiCyclic.Name = "aiCyclic"
            self.aiCyclic.Parent = self.GroupBox2
            self.aiCyclic.Left = 640
            self.aiCyclic.Top = 20
            self.aiCyclic.Cursor = crArrow
            # Create control: aiOnMsg = ActivityIndicator(self)
            self.aiOnMsg = ActivityIndicator(self)
            self.aiOnMsg.Name = "aiOnMsg"
            self.aiOnMsg.Parent = self.GroupBox2
            self.aiOnMsg.Left = 640
            self.aiOnMsg.Top = 59
            self.aiOnMsg.Cursor = crArrow
        finally:
            # End UI auto creation
            self.EndUIAutoCreation()
# Auto Generated Python Code, do not modify END [UI] ----------------
        self.Caption = self.GetLang('Raw CAN Transmit')
        self.FIsHex = True
        self.FNeedRefresh = True
        self.FIdxChn = 0
        self.FId = 0x123
        self.FDLC = 8
        self.FTriggerId = 0x100
        self.FIsTriggerTx = False
        self.FIsStd = True
        self.FIsData = True
        self.FIsFD = False
        # measurement start stop control
        self.OnRawCANEvent = self.RawCANEvent
        self.btnConnect = self.RegisterToolbarButton(self.GetLang('Connect'), 194, False)
        self.btnConnect.OnClick = self.OnConnectClick
        self.btnDisconnect = self.RegisterToolbarButton(self.GetLang('Disconnect'), 195, False)
        self.btnDisconnect.OnClick = self.OnDisconnectClick
        self.btnSystemMsgs = self.RegisterToolbarButton(self.GetLang('System Messages'), 217, True)
        self.OnConnectedCheck(app.is_connected())
        def OnMeasurementStart():
            self.OnConnectedCheck(True)
        def OnMeasurementStop():
            self.OnConnectedCheck(False)
        self.OnMeasurementStartedEvent = OnMeasurementStart
        self.OnMeasurementStoppedEvent = OnMeasurementStop
        def OnSystemMsgsClick(sender):
            frm = app.show_window_system_messages()
            frm.Left = self.Left + self.Width
            frm.Top = self.Top

        self.btnSystemMsgs.OnClick = OnSystemMsgsClick
        # trigger control
        def SetOnRxEvents():
            self.ClearCANFilters()
            for i in range(0, 32):
                self.AddCANFilterById(i, self.FTriggerId)
        def OnTriggerIdChange(sender):
            try:
                self.FTriggerId = int(self.edtOnMsg.Text, 0)
                SetOnRxEvents()
                self.log_hint(self.GetLang("Trigger id changed to") + ": " + hex(self.FTriggerId))
            except ValueError:
                self.log_error(self.GetLang("Invalid trigger id") + ": " + self.edtOnMsg.Text)
        self.edtOnMsg.OnChange = OnTriggerIdChange 
        def OnTriggerTxChange(sender):            
            self.FIsTriggerTx = self.chkOnMsg.Checked
            self.aiOnMsg.Animate = self.FIsTriggerTx
            SetOnRxEvents()
            if self.FIsTriggerTx:
                self.log_hint(self.GetLang("Auto transmission is activated on message rx"))
            else:
                self.log_hint(self.GetLang("Auto transmission is deactivated on message rx"))
        self.chkOnMsg.OnClick = OnTriggerTxChange
        # type control
        def OnTypeChange(sender):
            i = self.cbType.ItemIndex
            if 0 == i:
                self.FIsStd = True
                self.FIsData = True
                self.FIsFD = False
                self.log_hint(self.GetLang("Frame type changed to standard data frame"))
            elif 1 == i:
                self.FIsStd = True
                self.FIsData = False
                self.FIsFD = False
                self.log_hint(self.GetLang("Frame type changed to standard remote frame"))
            elif 2 == i:
                self.FIsStd = True
                self.FIsData = True
                self.FIsFD = True
                self.log_hint(self.GetLang("Frame type changed to standard FD frame"))
            elif 3 == i:
                self.FIsStd = False
                self.FIsData = True
                self.FIsFD = False
                self.log_hint(self.GetLang("Frame type changed to extended data frame"))
            elif 4 == i:
                self.FIsStd = False
                self.FIsData = False
                self.FIsFD = False
                self.log_hint(self.GetLang("Frame type changed to extended remote frame"))
            elif 5 == i:
                self.FIsStd = False
                self.FIsData = True
                self.FIsFD = True
                self.log_hint(self.GetLang("Frame type changed to extended FD frame"))
        self.cbType.OnChange = OnTypeChange
        # channel control
        def OnChnChange(sender):
            self.FIdxChn = self.cbChannel.ItemIndex
            self.log_hint(self.GetLang("Channel changed to") + " " + str(self.FIdxChn + 1))
        self.cbChannel.OnChange = OnChnChange 
        # hex edit control
        def OnHexEditChange(sender):
            self.FIsHex = self.chkHex.Checked
            self.RefreshData()
        self.chkHex.OnClick = OnHexEditChange 
        # id control
        def OnIdChange(sender):
            try:
                self.FId = int(self.edtId.Text, 0)
                self.SetConfiguration('id', self.edtId.Text)
                self.log_hint(self.GetLang("Id changed to") + " " + hex(self.FId))
            except ValueError:
                self.log_error(self.GetLang("Invalid Id") + ": " + self.edtId.Text)
        self.edtId.OnChange = OnIdChange
        # dlc control
        self.cbDLC.ItemIndex = self.FDLC
        def OnDLCChange(sender):
            self.FDLC = int(self.cbDLC.Text)
            self.log_hint(self.GetLang("DLC changed to") + " " + str(self.FDLC))
        self.cbDLC.OnChange = OnDLCChange 
        self.cbType.ItemIndex = 0
        self.cbChannel.Items.Assign(list(range(1, 33)))
        self.cbChannel.ItemIndex = self.FIdxChn
        self.grd.SetCell(0, 0, r"Bytes\Byte")
        self.FDataCache = list(range(0, 64))
        for i in range(1, 9):
            self.grd.SetCell(i, 0, i - 1)
        for i in range(0, 8):
            self.grd.SetCell(0, 1 + i, i * 8) 
        self.RefreshData()
        self.grd.OnSetEditText = self.OnSetEditTextEvent
        self.grd.OnSelectCell = self.OnSelectCell
        self.OnRefreshEvent = self.UIRefreshEvent
        self.btnTx.OnClick = self.OnTxClick
        # time interval control
        def OnIntervalChange(sender):
            try:
                self.FTimer.Interval = int(self.cbCyclic.Text, 0)
                print(self.GetLang("Timer interval changed to"), self.FTimer.Interval)
            except ValueError:
                self.log_error(self.GetLang("Invalid timer interval"))
        self.cbCyclic.OnChange = OnIntervalChange    
        # timer control
        self.FTimer = Timer(self)
        def OnTimer(sender):
            if app.is_connected():
                self.Transmit(False)
        self.FTimer.OnTimer = OnTimer
        self.FTimer.Enabled = False
        self.FTimer.Interval = 100
        # cyclic option control
        def OnCyclicChange(sender):
            self.FTimer.Interval = int(self.cbCyclic.Text, 0)
            self.FTimer.Enabled = self.chkCyclic.Checked
            self.aiCyclic.Animate = self.FTimer.Enabled 
            if self.FTimer.Enabled:
                self.log_hint(self.GetLang("Cyclic Timer is started"))
            else:
                self.log_hint(self.GetLang("Cyclic Timer is stopped"))
        self.chkCyclic.OnClick = OnCyclicChange
        # Application control
        app.set_current_application('TSMaster')
        self.log(self.GetLang('Current application is') + ': ' + app.get_current_application())
        # configuration
        self.edtId.Text = self.GetConfiguration('id', '0x123')
        self.cbDLC.Text = self.GetConfiguration('dlc', '8')
        
    # events    
    def OnSelectCell(self, Sender, Col, Row, CanSelect):
        if Col == 1 and Row == 1:
            self.log_hint(self.GetLang("First data byte is selected"))
            CanSelect.Value = True
    def OnSetEditTextEvent(self, Sender, ACol, ARow, AValue):
        i = 0
        try:
            i = int(AValue, 0)
            idx = (ACol-1) + (ARow-1) * 8    
            self.FDataCache[idx] = i 
            self.log_hint(self.GetLang("Data byte") + " " + str(idx) + ' ' + self.GetLang('changed to') + ': ' + hex(i))    
        except ValueError:
            if AValue != "":
                print(self.GetLang("Invalid value"), AValue)
    def RefreshData(self):
        for i in self.FDataCache:
            row = 1 + i // 8
            col = 1 + i % 8    
            if self.FIsHex:
                self.grd.SetCell(col, row, hex(self.FDataCache[i]))
            else:
                self.grd.SetCell(col, row, self.FDataCache[i])
    def UIRefreshEvent(self):
        if self.FNeedRefresh:
            self.FNeedRefresh = False
            self.RefreshData()
    def OnTxClick(self, sender):
        self.RefreshData()
        self.Transmit(True) 
    def Transmit(self, AUserClickResp):
        if app.is_connected():
            can = RawCAN(self.FId, self.FDLC)            
            can.is_data = self.FIsData
            can.is_std = self.FIsStd
            can.is_edl = self.FIsFD
            can.idx_chn = self.FIdxChn
            can.data = self.FDataCache
            if 0 == com.transmit_can_async(can):
                if AUserClickResp:
                    self.log_ok(self.GetLang("CAN message is transmitted"))
            else:
                if AUserClickResp:
                    self.log_error(self.GetLang("CAN message transmit failed"))
        else:
            self.log_error(self.GetLang("Tx failed: Application is not connected"))
    def RawCANEvent(self, ACAN):
        if self.FIsTriggerTx and (ACAN.id == self.FTriggerId):
            self.Transmit(False)
    def OnConnectClick(self, Sender):
        if 0 == app.connect():            
            self.OnConnectedCheck(True)
            app.make_toast(self.GetLang('Application Connected !'), lvlOK)
    def OnDisconnectClick(self, Sender):
        if 0 == app.disconnect():
            self.OnConnectedCheck(False)
            app.make_toast(self.GetLang('Application Disconnected !'), 3)
    def OnConnectedCheck(self, is_connected):
        if is_connected:
            self.btnConnect.Enabled = False
            self.btnDisconnect.Enabled = True
            self.log(self.GetLang('Measurement started'))
        else:
            self.btnConnect.Enabled = True
            self.btnDisconnect.Enabled = False
            self.log(self.GetLang('Measurement stopped'))
    def GetLang(self, AStr):
        return self.TranslateString(self.ExternalTypeName, AStr)

# Auto Generated Python Code, do not modify START [MAIN] ------------
if __name__ == "__main__":
    try:
        Raw_CAN_Transmit()
        Application.Run()
    except SystemExit:
        pass
# Auto Generated Python Code, do not modify END [MAIN] --------------
