320 |
350 |
321 self.DatatypeDescription, self.CommunicationObject, self.ManufacturerSpecific, \ |
351 self.DatatypeDescription, self.CommunicationObject, self.ManufacturerSpecific, \ |
322 self.ProfileSpecific, self.Reserved, self.AllSDOData = range(6) |
352 self.ProfileSpecific, self.Reserved, self.AllSDOData = range(6) |
323 |
353 |
324 self.Controler = controler |
354 self.Controler = controler |
325 |
355 |
|
356 self.SDOMonitorEntries = {} |
|
357 #----------------------------- SDO Monitor -------------------------------# |
|
358 self.RBList = ["ON","OFF"] |
|
359 |
|
360 self.SDOMonitorRB = wx.RadioBox(self, label=_("monitoring"), |
|
361 choices=self.RBList, majorDimension=2) |
|
362 |
|
363 self.SDOMonitorRB.SetSelection(1) |
|
364 self.Bind(wx.EVT_RADIOBOX, self.OnRadioBox, self.SDOMonitorRB) |
|
365 |
|
366 self.SDOMonitorGrid = wx.grid.Grid(self,size=wx.Size(850,150),style=wx.EXPAND |
|
367 |wx.ALIGN_CENTER_HORIZONTAL |
|
368 |wx.ALIGN_CENTER_VERTICAL) |
|
369 self.SDOMonitorGrid.Bind(gridlib.EVT_GRID_CELL_LEFT_DCLICK, |
|
370 self.onMonitorGridDoubleClick) |
|
371 |
|
372 #----------------------------- SDO Entries ----------------------------# |
|
373 self.SDOUpdateBtn = wx.Button(self, label=_("update")) |
|
374 self.SDOUpdateBtn.Bind(wx.EVT_BUTTON, self.OnSDOUpdate) |
|
375 |
|
376 self.SDOTraceThread = None |
|
377 self.SDOMonitoringFlag = False |
|
378 self.SDOValuesList = [] |
|
379 # Default SDO Page Number |
|
380 self.SDOPageNum = 2 |
|
381 |
|
382 #----------------------------- Sizer --------------------------------------# |
326 self.SDOManagementMainSizer = wx.BoxSizer(wx.VERTICAL) |
383 self.SDOManagementMainSizer = wx.BoxSizer(wx.VERTICAL) |
327 self.SDOManagementInnerMainSizer = wx.FlexGridSizer(cols=1, hgap=10, rows=2, vgap=10) |
384 self.SDOInfoBox = wx.StaticBox(self, label=_("SDO Entries")) |
328 |
385 self.SDOMonitorBox = wx.StaticBox(self, label=_("SDO Monitor")) |
329 self.SDOUpdate = wx.Button(self, label=_('update')) |
386 |
330 self.SDOUpdate.Bind(wx.EVT_BUTTON, self.SDOInfoUpdate) |
387 self.SDONoteBook = SDONoteBook(self, controler=self.Controler) |
331 |
388 self.SDOInfoBoxSizer = wx.StaticBoxSizer(self.SDOInfoBox, orient=wx.VERTICAL) |
332 self.CallSDONoteBook = SDONoteBook(self, controler=self.Controler) |
389 self.SDOMonitorBoxSizer = wx.StaticBoxSizer(self.SDOMonitorBox, |
333 self.SDOManagementInnerMainSizer.Add(self.SDOUpdate) |
390 orient=wx.VERTICAL) |
334 self.SDOManagementInnerMainSizer.Add(self.CallSDONoteBook, wx.ALL | wx.EXPAND) |
391 self.SDOInfoBoxSizer.Add(self.SDOUpdateBtn) |
335 |
392 |
336 self.SDOManagementMainSizer.Add(self.SDOManagementInnerMainSizer) |
393 self.SDOInfoBoxSizer.Add(self.SDONoteBook, wx.ALL|wx.EXPAND) |
337 |
394 self.SDOMonitorBoxSizer.Add(self.SDOMonitorRB) |
|
395 self.SDOMonitorBoxSizer.Add(self.SDOMonitorGrid) |
|
396 self.SDOManagementMainSizer.AddMany([self.SDOInfoBoxSizer, |
|
397 self.SDOMonitorBoxSizer]) |
338 self.SetSizer(self.SDOManagementMainSizer) |
398 self.SetSizer(self.SDOManagementMainSizer) |
339 |
399 |
340 def SDOInfoUpdate(self, event): |
400 #----------------------------- fill the contents --------------------------# |
341 """ |
401 #self.entries = self.Controler.CTNParent.CTNParent.GetEntriesList() |
342 Evenet handler for SDO "update" button. |
402 |
343 - Load SDO data from current slave |
403 slave = self.Controler.CTNParent.GetSlave(self.Controler.GetSlavePos()) |
344 @param event : wx.EVT_BUTTON object |
404 type_infos = slave.getType() |
345 """ |
405 device, alignment = self.Controler.CTNParent.GetModuleInfos(type_infos) |
346 self.Controler.CommonMethod.SaveSDOData = [] |
406 self.entries = device.GetEntriesList() |
|
407 |
|
408 self.Controler.CommonMethod.SDOVariables = [] |
|
409 self.Controler.CommonMethod.SDOSubEntryData = [] |
347 self.Controler.CommonMethod.ClearSDODataSet() |
410 self.Controler.CommonMethod.ClearSDODataSet() |
348 self.SDOFlag = False |
411 self.SDOParserXML(self.entries) |
349 |
412 self.SDONoteBook.CreateNoteBook() |
350 # Check whether beremiz connected or not. |
413 self.CreateSDOMonitorGrid() |
351 check_connect_flag = self.Controler.CommonMethod.CheckConnect(False) |
414 self.Refresh() |
|
415 |
|
416 def OnSDOUpdate(self, event): |
|
417 SlavePos = self.Controler.GetSlavePos() |
|
418 num = self.SDOPageNum - 1 |
|
419 if num < 0: |
|
420 for i in range(len(self.Controler.CommonMethod.SDOVariables)): |
|
421 data = self.Controler.GetCTRoot()._connector.GetSDOEntriesData( |
|
422 self.Controler.CommonMethod.SDOVariables[i], SlavePos) |
|
423 self.Controler.CommonMethod.SDOVariables[i] = data |
|
424 else : |
|
425 SDOUploadEntries = self.Controler.CommonMethod.SDOVariables[num] |
|
426 data = self.Controler.GetCTRoot()._connector.GetSDOEntriesData(SDOUploadEntries, SlavePos) |
|
427 self.Controler.CommonMethod.SDOVariables[num] = data |
|
428 |
|
429 self.SDONoteBook.CreateNoteBook() |
|
430 self.Refresh() |
|
431 |
|
432 def OnRadioBox(self, event): |
|
433 """ |
|
434 There are two selections that are on and off. |
|
435 If the on is selected, the monitor thread begins to run. |
|
436 If the off is selected, the monitor thread gets off. |
|
437 @param event: wx.EVT_RADIOBOX object |
|
438 """ |
|
439 on, off = range(2) |
|
440 |
|
441 if event.GetInt() == on: |
|
442 CheckThreadFlag = self.SDOMonitoringThreadOn() |
|
443 if not CheckThreadFlag: |
|
444 self.SDOMonitorRB.SetSelection(off) |
|
445 elif event.GetInt() == off: |
|
446 self.SDOMonitoringThreadOff() |
|
447 |
|
448 def SDOMonitoringThreadOn(self): |
|
449 check_connect_flag = self.Controler.CommonMethod.CheckConnect(cyclic_flag = False) |
352 if check_connect_flag: |
450 if check_connect_flag: |
353 self.SDOs = self.Controler.CommonMethod.GetSlaveSDOFromSlave() |
451 self.SetSDOTraceValues(self.SDOMonitorEntries) |
354 # SDOFlag is "False", user click "Cancel" button |
452 self.Controler.GetCTRoot()._connector.GetSDOData() |
355 self.SDOFlag = self.SDOParser() |
453 self.SDOTraceThread = Thread(target=self.SDOMonitorThreadProc) |
356 |
454 self.SDOMonitoringFlag = True |
357 if self.SDOFlag : |
455 self.SDOTraceThread.start() |
358 self.CallSDONoteBook.CreateNoteBook() |
456 return check_connect_flag |
359 self.Refresh() |
457 |
360 |
458 def SDOMonitoringThreadOff(self): |
361 def SDOParser(self): |
459 check_connect_flag = self.Controler.CommonMethod.CheckConnect(cyclic_flag = False) |
362 """ |
460 if check_connect_flag: |
363 Parse SDO data set that obtain "SDOInfoUpdate" Method |
461 self.SDOMonitoringFlag = False |
364 @return True or False |
462 if self.SDOTraceThread is not None: |
365 """ |
463 self.SDOTraceThread.join() |
366 |
464 self.SDOTraceThread = None |
367 slaveSDO_progress = wx.ProgressDialog("Slave SDO Monitoring", "Now Uploading...", |
465 self.Controler.GetCTRoot()._connector.StopSDOThread() |
368 maximum = len(self.SDOs.splitlines()), parent=self, |
466 |
369 style = wx.PD_CAN_ABORT | wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME | |
467 def SetSDOTraceValues(self, SDOMonitorEntries): |
370 wx.PD_ESTIMATED_TIME | wx.PD_REMAINING_TIME | |
468 SlavePos = self.Controler.GetSlavePos() |
371 wx.PD_AUTO_HIDE | wx.PD_SMOOTH) |
469 check_connect_flag = self.Controler.CommonMethod.CheckConnect(cyclic_flag = True) |
372 |
470 if check_connect_flag: |
373 # If keep_going flag is False, SDOParser method is stop and return "False". |
471 self.Controler.GetCTRoot()._connector.SetSDOTraceValues(SDOMonitorEntries, SlavePos) |
374 keep_going = True |
472 |
375 count = 0 |
473 def SDOMonitorThreadProc(self): |
376 |
474 while self.SDOMonitoringFlag and self.Controler.GetCTRoot()._connector.PLCStatus != "Started": |
377 # SDO data example |
475 self.SDOValuesList = self.Controler.GetCTRoot()._connector.GetSDOData() |
378 # SDO 0x1000, "Device type" |
476 LocalData = self.SDOValuesList[0].items() |
379 # 0x1000:00,r-r-r-,uint32,32 bit,"Device type",0x00020192, 131474 |
477 LocalData.sort() |
380 for details_line in self.SDOs.splitlines(): |
478 if self.SDOValuesList[1] != self.Controler.GetSlavePos(): |
381 count += 1 |
479 continue |
382 line_token = details_line.split("\"") |
480 row = 0 |
383 # len(line_token[2]) case : SDO 0x1000, "Device type" |
481 for (idx, subidx), data in LocalData: |
384 if len(line_token[2]) == 0: |
482 self.SDOMonitorGrid.SetCellValue(row, 6, str(data["value"])) |
385 title_name = line_token[1] |
483 row += 1 |
386 # else case : 0x1000:00,r-r-r-,uint32,32 bit,"Device type",0x00020192, 131474 |
484 time.sleep(0.5) |
387 else : |
485 |
388 # line_token = ['0x1000:00,r-r-r-,uint32,32 bit,', 'Device type', ',0x00020192, 131474'] |
486 def CreateSDOMonitorGrid(self): |
389 token_head, name, token_tail = line_token |
487 """ |
|
488 It creates SDO Monitor table and specifies cell size and labels. |
|
489 """ |
|
490 self.SDOMonitorGrid.CreateGrid(0,7) |
|
491 SDOCellSize = [(0, 65), (1, 65), (2, 50), (3, 70), |
|
492 (4, 40), (5, 450), (6, 85)] |
|
493 |
|
494 for (index, size) in SDOCellSize: |
|
495 self.SDOMonitorGrid.SetColSize(index, size) |
|
496 |
|
497 self.SDOMonitorGrid.SetRowLabelSize(0) |
|
498 |
|
499 SDOTableLabel = [(0, "Index"), (1, "Subindex"), (2, "Access"), |
|
500 (3, "Type"), (4, "Size"), (5, "Name"), (6, "Value")] |
|
501 |
|
502 for (index, label) in SDOTableLabel: |
|
503 self.SDOMonitorGrid.SetColLabelValue(index, label) |
|
504 self.SDOMonitorGrid.SetColLabelAlignment(index, wx.ALIGN_CENTER) |
|
505 |
|
506 def onMonitorGridDoubleClick(self, event): |
|
507 """ |
|
508 Event Handler for double click on the SDO entries table. |
|
509 It adds the entry into the SDO monitor table. |
|
510 If the entry is already in the SDO monitor table, |
|
511 then it's removed from the SDO monitor table. |
|
512 @pram event: gridlib.EVT_GRID_CELL_LEFT_DCLICK object |
|
513 """ |
|
514 row = event.GetRow() |
|
515 idx = self.SDOMonitorGrid.GetCellValue(row, 0) |
|
516 subIdx = self.SDOMonitorGrid.GetCellValue(row, 1) |
|
517 |
|
518 del self.SDOMonitorEntries[(idx, subIdx)] |
|
519 self.SDOMonitorGrid.DeleteRows(row, 1) |
|
520 # add jblee |
|
521 self.SetSDOTraceValues(self.SDOMonitorEntries) |
|
522 self.SDOMonitorGrid.Refresh() |
|
523 |
|
524 def SDOParserXML(self, entries): |
|
525 """ |
|
526 Parse SDO data set that obtain "ESI file" |
|
527 @param entries: SDO entry list |
|
528 """ |
|
529 entries_list = entries.items() |
|
530 entries_list.sort() |
|
531 self.ForDefaultValueFlag = False |
|
532 self.CompareValue = "" |
|
533 self.sub_entry_value_list = [] |
|
534 |
|
535 for (index, subidx), entry in entries_list: |
|
536 # exclude entry that isn't in the objects |
|
537 check_mapping = entry["PDOMapping"] |
|
538 if check_mapping is "T" or check_mapping is "R": |
|
539 if "PDO index" not in entry.keys(): |
|
540 continue |
|
541 |
|
542 idx = "0" + entry["Index"].strip("#") |
|
543 #subidx = hex(int(entry["SubIndex"], 0)) |
|
544 try : |
|
545 subidx = "0x" + entry["SubIndex"] |
|
546 except : |
|
547 subidx = "0x0" |
|
548 datatype = entry["Type"] |
|
549 |
|
550 try : |
|
551 default_value = entry["DefaultData"] |
|
552 except : |
|
553 default_value = " --- " |
|
554 # Result of SlaveSDO data parsing. (data type : dictionary) |
|
555 self.Data = {'idx':idx, 'subIdx':subidx, 'access':entry["Access"], |
|
556 'type':datatype, 'size': str(entry["BitSize"]), |
|
557 'name':entry["Name"], 'value':default_value} |
|
558 category_divide_value = [0x1000, 0x2000, 0x6000, 0xa000, 0xffff] |
390 |
559 |
391 # token_head = ['0x1000:00', 'r-r-r-', 'uint32', '32 bit', ''] |
560 for count in range(len(category_divide_value)) : |
392 token_head = token_head.split(",") |
561 if int(idx, 0) < category_divide_value[count]: |
393 ful_idx, access, type, size, empty = token_head |
562 self.Controler.CommonMethod.SDOVariables[count].append(self.Data) |
394 # ful_idx.split(":") = ['0x1000', '00'] |
563 break |
395 idx, sub_idx = ful_idx.split(":") |
564 |
396 |
565 self.Controler.CommonMethod.SDOSubEntryData = self.sub_entry_value_list |
397 # token_tail = ['', '0x00020192', '131474'] |
|
398 token_tail = token_tail.split(",") |
|
399 try : |
|
400 empty, hex_val, dec_val = token_tail |
|
401 |
|
402 # SDO data is not return "dec value" |
|
403 # line example : |
|
404 # 0x1702:01,rwr-r-,uint32,32 bit," 1st mapping", ---- |
|
405 except : |
|
406 empty, hex_val = token_tail |
|
407 |
|
408 name_after_check = self.StringTest(name) |
|
409 |
|
410 # convert hex type |
|
411 sub_idx = "0x" + sub_idx |
|
412 |
|
413 if type == "octet_string": |
|
414 hex_val = ' ---- ' |
|
415 |
|
416 # SResult of SlaveSDO data parsing. (data type : dictionary) |
|
417 self.Data = {'idx':idx.strip(), 'subIdx':sub_idx.strip(), 'access':access.strip(), |
|
418 'type':type.strip(), 'size':size.strip(), 'name':name_after_check.strip("\""), |
|
419 'value':hex_val.strip(), "category":title_name.strip("\"")} |
|
420 |
|
421 category_divide_value = [0x1000, 0x2000, 0x6000, 0xa000, 0xffff] |
|
422 |
|
423 for count in range(len(category_divide_value)) : |
|
424 if int(idx, 0) < category_divide_value[count]: |
|
425 self.Controler.CommonMethod.SaveSDOData[count].append(self.Data) |
|
426 break |
|
427 |
|
428 self.Controler.CommonMethod.SaveSDOData[self.AllSDOData].append(self.Data) |
|
429 |
|
430 if count >= len(self.SDOs.splitlines()) / 2: |
|
431 (keep_going, skip) = slaveSDO_progress.Update(count, "Please waiting a moment!!") |
|
432 else: |
|
433 (keep_going, skip) = slaveSDO_progress.Update(count) |
|
434 |
|
435 # If user click "Cancel" loop suspend immediately |
|
436 if (keep_going == False): |
|
437 break |
|
438 |
|
439 slaveSDO_progress.Destroy() |
|
440 return keep_going |
|
441 |
|
442 def StringTest(self, check_string): |
|
443 """ |
|
444 Test value 'name' is alphanumeric |
|
445 @param check_string : input data for check |
|
446 @return result : output data after check |
|
447 """ |
|
448 # string.printable is print this result |
|
449 #'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ |
|
450 #!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c |
|
451 allow_range = string.printable |
|
452 result = check_string |
|
453 for i in range(0, len(check_string)): |
|
454 # string.isalnum() is check whether string is alphanumeric or not |
|
455 if check_string[len(check_string)-1-i:len(check_string)-i] in allow_range : |
|
456 result = check_string[:len(check_string) - i] |
|
457 break |
|
458 return result |
|
459 |
|
460 |
566 |
461 #------------------------------------------------------------------------------- |
567 #------------------------------------------------------------------------------- |
462 # For SDO Notebook (divide category) |
568 # For SDO Notebook (divide category) |
463 #------------------------------------------------------------------------------- |
569 #------------------------------------------------------------------------------- |
464 class SDONoteBook(wx.Notebook): |
570 class SDONoteBook(wx.Notebook): |
570 |
684 |
571 def SetTableValue(self): |
685 def SetTableValue(self): |
572 """ |
686 """ |
573 Cell is filled by new parsing data |
687 Cell is filled by new parsing data |
574 """ |
688 """ |
575 sdo_list = ['idx', 'subIdx', 'access', 'type', 'size', 'category', 'name', 'value'] |
689 sdo_list = ['idx', 'subIdx', 'access', 'type', 'size', 'name', 'value'] |
|
690 count = 0 |
576 for row_idx in range(len(self.SDOs)): |
691 for row_idx in range(len(self.SDOs)): |
577 for col_idx in range(len(self.SDOs[row_idx])): |
692 for col_idx in range(len(self.SDOs[row_idx])): |
578 self.SetCellValue(row_idx, col_idx, self.SDOs[row_idx][sdo_list[col_idx]]) |
693 |
|
694 # the top entries that have sub index is shaded. |
|
695 if int(self.SDOs[row_idx]['subIdx'], 16) == 0x00: |
|
696 try: |
|
697 if int(self.SDOs[row_idx + 1]['subIdx'], 16) is not 0x00: |
|
698 self.SetCellBackgroundColour(row_idx, col_idx, \ |
|
699 wx.LIGHT_GREY) |
|
700 except: |
|
701 pass |
|
702 |
|
703 if self.SDOs[row_idx][sdo_list[col_idx]] == "modifying": |
|
704 if len(self.sub_entry_value) == count: |
|
705 continue |
|
706 self.SetCellValue(row_idx, col_idx, self.sub_entry_value[count]) |
|
707 count += 1 |
|
708 else : |
|
709 self.SetCellValue(row_idx, col_idx, \ |
|
710 self.SDOs[row_idx][sdo_list[col_idx]]) |
|
711 |
579 self.SetReadOnly(row_idx, col_idx, True) |
712 self.SetReadOnly(row_idx, col_idx, True) |
|
713 |
580 if col_idx < 5 : |
714 if col_idx < 5 : |
581 self.SetCellAlignment(row_idx, col_idx, wx.ALIGN_CENTRE, wx.ALIGN_CENTRE) |
715 self.SetCellAlignment(row_idx, col_idx, wx.ALIGN_CENTER, wx.ALIGN_CENTER) |
582 |
716 |
583 def CheckSDODataAccess(self, row): |
717 def CheckSDODataAccess(self, row): |
584 """ |
718 """ |
585 CheckSDODataAccess method is checking that access data has "w" |
719 check that access field has "rw" |
586 Access field consist 6 char, if mean |
|
587 rw rw rw |
|
588 (preop) (safeop) (op) |
|
589 Example Access field : rwrwrw, rwrw-- |
|
590 @param row : Selected cell by user |
720 @param row : Selected cell by user |
591 @return Write_flag : If data has "w", flag is true |
721 @return Write_flag : If data has "w", flag is true |
592 """ |
722 """ |
593 write_flag = False |
|
594 check = self.SDOs[row]['access'] |
723 check = self.SDOs[row]['access'] |
595 if check[1:2] == 'w' : |
724 if check == "rw": |
596 self.Controler.CommonMethod.Check_PREOP = True |
|
597 write_flag = True |
|
598 if check[3:4] == 'w' : |
|
599 self.Controler.CommonMethod.Check_SAFEOP = True |
|
600 write_flag = True |
|
601 if check[5:] =='w' : |
|
602 self.Controler.CommonMethod.Check_OP = True |
|
603 write_flag = True |
|
604 |
|
605 return write_flag |
|
606 |
|
607 def DecideSDODownload(self, state): |
|
608 """ |
|
609 compare current state and "access" field, |
|
610 result notify SDOModifyDialog method |
|
611 @param state : current slave state |
|
612 @return True or False |
|
613 """ |
|
614 # Example of 'state' parameter : "0 0:0 PREOP + EL9800 (V4.30) (PIC24, SPI, ET1100)" |
|
615 state = state[self.Controler.GetSlavePos()].split(" ")[2] |
|
616 if state == "PREOP" and self.Controler.CommonMethod.Check_PREOP : |
|
617 return True |
725 return True |
618 elif state == "SAFEOP" and self.Controler.CommonMethod.Check_SAFEOP : |
726 else: |
619 return True |
727 return False |
620 elif state == "OP" and self.Controler.CommonMethod.Check_OP : |
|
621 return True |
|
622 |
|
623 return False |
|
624 |
728 |
625 def ClearStateFlag(self): |
729 def ClearStateFlag(self): |
626 """ |
730 """ |
627 Initialize StateFlag |
731 Initialize StateFlag |
628 StateFlag is notice SDOData access each slave state |
732 StateFlag is notice SDOData access each slave state |
629 """ |
733 """ |
630 self.Controler.CommonMethod.Check_PREOP = False |
734 self.Controler.CommonMethod.Check_PREOP = False |
631 self.Controler.CommonMethod.Check_SAFEOP = False |
735 self.Controler.CommonMethod.Check_SAFEOP = False |
632 self.Controler.CommonMethod.Check_OP = False |
736 self.Controler.CommonMethod.Check_OP = False |
633 |
737 |
634 def SDOModifyDialog (self, event): |
738 def onGridDoubleClick (self, event): |
635 """ |
739 """ |
636 Create dialog for SDO value modify |
740 Create dialog for SDO value modify |
637 if user enter data, perform command "ethercat download" |
741 if user enter data, perform command "ethercat download" |
638 @param event : gridlib.EVT_GRID_CELL_LEFT_DCLICK object |
742 @param event : gridlib.EVT_GRID_CELL_LEFT_DCLICK object |
639 """ |
743 """ |
640 self.ClearStateFlag() |
744 self.ClearStateFlag() |
641 |
745 |
642 # CheckSDODataAccess is checking that OD(Object Dictionary) has "w" |
746 # CheckSDODataAccess is checking that OD(Object Dictionary) has "w" |
643 if event.GetCol() == 7 and self.CheckSDODataAccess(event.GetRow()) : |
747 if event.GetCol() == 6 and self.CheckSDODataAccess(event.GetRow()) : |
644 dlg = wx.TextEntryDialog (self, "Enter hex or dec value (if enter dec value, it automatically conversed hex value)", |
748 dlg = wx.TextEntryDialog (self, |
645 "SDOModifyDialog", style = wx.OK | wx.CANCEL) |
749 "Enter hex or dec value (if enter dec value, " \ |
|
750 + "it automatically conversed hex value)", |
|
751 "SDOModifyDialog", style = wx.OK | wx.CANCEL) |
646 |
752 |
647 start_value = self.GetCellValue(event.GetRow(), event.GetCol()) |
753 start_value = self.GetCellValue(event.GetRow(), event.GetCol()) |
648 dlg.SetValue(start_value) |
754 dlg.SetValue(start_value) |
649 |
755 |
650 if dlg.ShowModal() == wx.ID_OK: |
756 if dlg.ShowModal() == wx.ID_OK: |
651 try : |
757 # Check whether beremiz connected or not. |
652 int(dlg.GetValue(), 0) |
758 # If this method is called cyclically, set the cyclic flag true |
653 # check "Access" field |
759 check_connect_flag = self.Controler.CommonMethod.CheckConnect(cyclic_flag = False) |
654 if self.DecideSDODownload(self.Controler.CommonMethod.SlaveState[self.Controler.GetSlavePos()]) : |
760 if check_connect_flag: |
|
761 try : |
|
762 input_val = hex(int(dlg.GetValue(), 0)) |
655 # Request "SDODownload" |
763 # Request "SDODownload" |
656 self.Controler.CommonMethod.SDODownload(self.SDOs[event.GetRow()]['type'], self.SDOs[event.GetRow()]['idx'], |
764 return_val = self.Controler.CommonMethod.SDODownload( |
657 self.SDOs[event.GetRow()]['subIdx'], dlg.GetValue()) |
765 self.SDOs[event.GetRow()]["type"], |
658 self.SetCellValue(event.GetRow(), event.GetCol(), hex(int(dlg.GetValue(), 0))) |
766 self.SDOs[event.GetRow()]["idx"], |
659 else : |
767 self.SDOs[event.GetRow()]["subIdx"], |
660 self.Controler.CommonMethod.CreateErrorDialog('You cannot SDO download this state') |
768 dlg.GetValue()) |
661 # Error occured process of "int(variable)" |
769 if return_val is "": |
662 # User input is not hex, dec value |
770 SDOUploadEntry = {"idx" : self.SDOs[event.GetRow()]["idx"], |
663 except ValueError: |
771 "subIdx" : self.SDOs[event.GetRow()]["subIdx"], |
664 self.Controler.CommonMethod.CreateErrorDialog('You can input only hex, dec value') |
772 "size" : self.SDOs[event.GetRow()]["size"] |
665 |
773 } |
|
774 data = self.Controler.GetCTRoot()._connector.GetSDOEntryData( |
|
775 SDOUploadEntry, self.Controler.GetSlavePos()) |
|
776 hex_val = hex(data)[:-1] |
|
777 |
|
778 # download data check |
|
779 if input_val == hex_val: |
|
780 display_val = "%s(%d)" % (hex_val, data) |
|
781 self.SetCellValue(event.GetRow(), event.GetCol(), |
|
782 display_val) |
|
783 else : |
|
784 self.Controler.CommonMethod.CreateErrorDialog(\ |
|
785 'SDO Value not completely download, please try again') |
|
786 else: |
|
787 self.Controler.GetCTRoot().logger.write_error(return_val) |
|
788 |
|
789 # Error occured process of "int(variable)" |
|
790 # User input is not hex, dec value |
|
791 except ValueError: |
|
792 self.Controler.CommonMethod.CreateErrorDialog(\ |
|
793 'You can input only hex, dec value') |
|
794 else: |
|
795 SDOPanel = self.parent.parent |
|
796 row = event.GetRow() |
|
797 |
|
798 idx = self.SDOs[row]["idx"] |
|
799 subIdx = self.SDOs[row]["subIdx"] |
|
800 SDOPanel.SDOMonitorEntries[(idx, subIdx)] = { |
|
801 "access": self.SDOs[row]["access"], |
|
802 "type": self.SDOs[row]["type"], |
|
803 "size": self.SDOs[row]["size"], |
|
804 "name": self.SDOs[row]["name"], |
|
805 # add jblee |
|
806 "value": ""} |
|
807 |
|
808 del_rows = SDOPanel.SDOMonitorGrid.GetNumberRows() |
|
809 |
|
810 try: |
|
811 SDOPanel.SDOMonitorGrid.DeleteRows(0, del_rows) |
|
812 except: |
|
813 pass |
|
814 |
|
815 SDOPanel.SDOMonitorGrid.AppendRows(len(SDOPanel.SDOMonitorEntries)) |
|
816 SDOPanel.SetSDOTraceValues(SDOPanel.SDOMonitorEntries) |
|
817 |
|
818 SME_list = SDOPanel.SDOMonitorEntries.items() |
|
819 SME_list.sort() |
|
820 |
|
821 gridRow = 0 |
|
822 for (idx, subIdx), entry in SME_list: |
|
823 SDOPanel.SDOMonitorGrid.SetCellValue(gridRow, 0, str(idx)) |
|
824 SDOPanel.SDOMonitorGrid.SetCellValue(gridRow, 1, str(subIdx)) |
|
825 for col, key in [(2, "access"), |
|
826 (3, "type"), |
|
827 (4, "size"), |
|
828 (5, "name")]: |
|
829 SDOPanel.SDOMonitorGrid.SetCellValue(gridRow, col, entry[key]) |
|
830 for col in range(7): |
|
831 SDOPanel.SDOMonitorGrid.SetReadOnly(gridRow, col, True) |
|
832 if col < 5 : |
|
833 SDOPanel.SDOMonitorGrid.SetCellAlignment(\ |
|
834 gridRow, col, wx.ALIGN_CENTER, wx.ALIGN_CENTER) |
|
835 gridRow += 1 |
|
836 |
|
837 SDOPanel.SDOMonitorGrid.Refresh() |
666 |
838 |
667 #------------------------------------------------------------------------------- |
839 #------------------------------------------------------------------------------- |
668 # For PDO Monitoring Panel |
840 # For PDO Mapping Panel |
669 # PDO Class UI : Panel -> Choicebook (RxPDO, TxPDO) -> |
841 # PDO Class UI : Panel -> Choicebook (RxPDO, TxPDO) -> |
670 # Notebook (PDO Index) -> Grid (PDO entry) |
842 # Notebook (PDO Index) -> Grid (PDO entry) |
671 #------------------------------------------------------------------------------- |
843 #------------------------------------------------------------------------------- |
672 class PDOPanelClass(wx.Panel): |
844 class PDOPanelClass(wx.Panel): |
673 def __init__(self, parent, controler): |
845 def __init__(self, parent, controler): |
676 @param parent: Reference to the parent EtherCATManagementTreebook class |
848 @param parent: Reference to the parent EtherCATManagementTreebook class |
677 @param controler: _EthercatSlaveCTN class in EthercatSlave.py |
849 @param controler: _EthercatSlaveCTN class in EthercatSlave.py |
678 """ |
850 """ |
679 wx.Panel.__init__(self, parent, -1) |
851 wx.Panel.__init__(self, parent, -1) |
680 self.Controler = controler |
852 self.Controler = controler |
681 |
853 sizer = wx.FlexGridSizer(cols=1, hgap=20,rows=3, vgap=20) |
682 self.PDOMonitoringEditorMainSizer = wx.BoxSizer(wx.VERTICAL) |
854 line = wx.StaticText(self, -1, "\n In order to control Ethercat device, user must select proper PDO set.\ |
683 self.PDOMonitoringEditorInnerMainSizer = wx.FlexGridSizer(cols=1, hgap=10, rows=2, vgap=10) |
855 \n Each PDO sets describe operation modes (CSP, CSV, CST) supported by Ethercat devices.\ |
684 |
856 \n\n PDOs have two types, RxPDO and TxPDO.\ |
685 self.CallPDOChoicebook = PDOChoicebook(self, controler=self.Controler) |
857 \n - RxPDO refers to the Receive Process Data Object. It means the control parameters which sent from controller to the EtherCAT Slave device.\ |
686 self.PDOMonitoringEditorInnerMainSizer.Add(self.CallPDOChoicebook, wx.ALL) |
858 \n In general, ControlWord (0x6040), Modes of Operations (0x6060), and TargetPosition (0x607A) are regarded as RxPDO.\ |
687 |
859 \n - TxPDO refers to the Transmit Process Data Object. It used to report status of EtherCAT Slave device to the controller in order to calibrate their next actuation.\ |
688 self.PDOMonitoringEditorMainSizer.Add(self.PDOMonitoringEditorInnerMainSizer) |
860 \n StatusWord (0x6041), Modes of Operation Display (0x6061), and ActualPosition (0x607A) include in TxPDO.\ |
689 |
861 \n\n PDO Mapping feature provides available RxPDO and TxPDO sets which defined in Ethercat slave description XML.\ |
690 self.SetSizer(self.PDOMonitoringEditorMainSizer) |
862 \n If there is no selection of PDO set, first set (0x1600, 0x1A00) will be chosen as default configuration.") |
|
863 |
|
864 sizer.Add(line) |
|
865 self.SetSizer(sizer) |
|
866 |
|
867 class RxPDOPanelClass(wx.Panel): |
|
868 def __init__(self, parent, controler): |
|
869 """ |
|
870 Constructor |
|
871 @param parent: Reference to the parent EtherCATManagementTreebook class |
|
872 @param controler: _EthercatSlaveCTN class in EthercatSlave.py |
|
873 """ |
|
874 wx.Panel.__init__(self, parent, -1) |
|
875 self.Controler = controler |
|
876 |
|
877 # add jblee |
|
878 #self.PDOIndexList = ["RxPDO"] |
|
879 self.PDOIndexList = [] |
|
880 self.LoadPDOSelectData() |
|
881 |
|
882 #HSAHN ADD. 2015.7.26 PDO Select Function ADD |
|
883 self.Controler.CommonMethod.RequestPDOInfo() |
|
884 self.PDOcheckBox = [] |
|
885 self.rx_pdo_entries = self.Controler.CommonMethod.GetRxPDOCategory() |
|
886 if len(self.rx_pdo_entries): |
|
887 for i in range(len(self.rx_pdo_entries)): |
|
888 self.PDOcheckBox.append(wx.CheckBox(self, label=str(hex(self.rx_pdo_entries[i]['pdo_index'])), size=(120,15))) |
|
889 if not self.Controler.SelectedRxPDOIndex and self.rx_pdo_entries[i]['sm'] is not None: |
|
890 self.PDOcheckBox[-1].SetValue(True) |
|
891 self.Controler.SelectedRxPDOIndex.append(int(self.PDOcheckBox[-1].GetLabel(), 0)) |
|
892 self.InitSavePDO() |
|
893 elif self.rx_pdo_entries[i]['pdo_index'] in self.Controler.SelectedRxPDOIndex: |
|
894 self.PDOIndexList.append(str(hex(self.rx_pdo_entries[i]['pdo_index']))) |
|
895 self.PDOcheckBox[-1].SetValue(True) |
|
896 |
|
897 for cb in self.PDOcheckBox: |
|
898 self.Bind(wx.EVT_CHECKBOX, self.PDOSelectCheck, cb) |
|
899 |
|
900 self.PDOListBox = wx.StaticBox(self, label=_("PDO Mapping Select")) |
|
901 self.PDOListBoxSizer = wx.StaticBoxSizer(self.PDOListBox, orient=wx.HORIZONTAL) |
|
902 self.RxPDOListBox = wx.StaticBox(self, label=_("RxPDO")) |
|
903 self.RxPDOListBoxSizer = wx.StaticBoxSizer(self.RxPDOListBox, orient=wx.VERTICAL) |
|
904 self.RxPDOListBoxInnerSizer = wx.FlexGridSizer(cols=3, hgap=5, rows=10, vgap=5) |
|
905 self.RxPDOListBoxInnerSizer.AddMany(self.PDOcheckBox[0:len(self.rx_pdo_entries)]) |
|
906 self.RxPDOListBoxSizer.Add(self.RxPDOListBoxInnerSizer) |
|
907 self.PDOListBoxSizer.Add(self.RxPDOListBoxSizer) |
|
908 self.PDOWarningText = wx.StaticText(self, -1, |
|
909 " *Warning*\n\n By default configuration, \n\n first mapping set is selected. \n\n Choose the PDO mapping!", |
|
910 size=(220, -1)) |
|
911 self.PDOListBoxSizer.Add(self.PDOWarningText) |
|
912 |
|
913 self.PDOMonitoringEditorMainSizer = wx.BoxSizer(wx.VERTICAL) |
|
914 self.PDOMonitoringEditorInnerMainSizer = wx.FlexGridSizer(cols=1, hgap=10, rows=2, vgap=10) |
|
915 |
|
916 |
|
917 self.CallPDOChoicebook = PDONoteBook(self, controler=self.Controler, name="Rx") |
|
918 self.PDOMonitoringEditorInnerMainSizer.Add(self.CallPDOChoicebook, wx.ALL) |
|
919 |
|
920 self.PDOInformationBox = wx.StaticBox(self, label=_("RxPDO Mapping List")) |
|
921 self.PDOInformationBoxSizer = wx.StaticBoxSizer(self.PDOInformationBox, orient=wx.VERTICAL) |
|
922 self.PDOInformationBoxSizer.Add(self.PDOMonitoringEditorInnerMainSizer) |
|
923 |
|
924 self.PDOMonitoringEditorMainSizer.Add(self.PDOListBoxSizer) |
|
925 self.PDOMonitoringEditorMainSizer.Add(self.PDOInformationBoxSizer) |
|
926 self.SetSizer(self.PDOMonitoringEditorMainSizer) |
|
927 |
|
928 # add jblee |
|
929 self.PDOExcludeCheck() |
|
930 else: |
|
931 sizer = wx.FlexGridSizer(cols=1, hgap=20,rows=3, vgap=20) |
|
932 line = wx.StaticText(self, -1, "\n This device does not support RxPDO.") |
|
933 |
|
934 sizer.Add(line) |
|
935 self.SetSizer(sizer) |
|
936 |
|
937 def LoadPDOSelectData(self): |
|
938 RxPDOData = self.Controler.BaseParams.getRxPDO() |
|
939 RxPDOs = [] |
|
940 if RxPDOData != "None": |
|
941 RxPDOs = RxPDOData.split() |
|
942 if RxPDOs : |
|
943 for RxPDO in RxPDOs : |
|
944 self.Controler.SelectedRxPDOIndex.append(int(RxPDO, 0)) |
|
945 |
|
946 def PDOSelectCheck(self, event): |
|
947 # add jblee for Save User Select |
|
948 cb = event.GetEventObject() |
|
949 # prevent duplicated check |
|
950 if cb.GetValue() and int(cb.GetLabel(), 0) not in self.Controler.SelectedRxPDOIndex: |
|
951 self.Controler.SelectedRxPDOIndex.append(int(cb.GetLabel(), 0)) |
|
952 self.PDOIndexList.append(cb.GetLabel()) |
|
953 else: |
|
954 self.Controler.SelectedRxPDOIndex.remove(int(cb.GetLabel(), 0)) |
|
955 self.PDOIndexList.remove(cb.GetLabel()) |
|
956 |
|
957 data = "" |
|
958 for PDOIndex in self.PDOIndexList: |
|
959 data = data + " " + PDOIndex |
|
960 |
|
961 self.Controler.BaseParams.setRxPDO(data) |
|
962 self.Controler.GetCTRoot().CTNRequestSave() |
|
963 |
|
964 self.PDOExcludeCheck() |
|
965 |
|
966 def InitSavePDO(self): |
|
967 for PDOIndex in self.Controler.SelectedRxPDOIndex: |
|
968 self.PDOIndexList.append(str(hex(PDOIndex))) |
|
969 |
|
970 data = "" |
|
971 for PDOIndex in self.PDOIndexList: |
|
972 data = data + " " + PDOIndex |
|
973 |
|
974 self.Controler.BaseParams.setRxPDO(data) |
|
975 |
|
976 # 2016.06.21 |
|
977 # add jblee for check exclude pdo list |
|
978 def PDOExcludeCheck(self): |
|
979 #files = os.listdir(self.Controler.CTNPath()) |
|
980 #filepath = os.path.join(self.Controler.CTNPath(), "DataForPDO.txt") |
|
981 CurIndexs = self.Controler.SelectedRxPDOIndex |
|
982 for CB in self.PDOcheckBox: |
|
983 if len(CB.GetLabel().split()) > 1: |
|
984 CB.Enable() |
|
985 CB.SetLabel(CB.GetLabel().split()[0]) |
|
986 |
|
987 for pdo in self.rx_pdo_entries: |
|
988 for CurIndex in CurIndexs: |
|
989 if pdo["pdo_index"] == CurIndex: |
|
990 ex_list = pdo["exclude_list"] |
|
991 for ex_item in ex_list: |
|
992 for CB in self.PDOcheckBox: |
|
993 if CB.GetLabel() == hex(ex_item): |
|
994 CB.SetLabel(CB.GetLabel() + " (Excluded)") |
|
995 CB.Disable() |
|
996 |
|
997 def RefreshPDOInfo(self): |
|
998 pass |
691 |
999 |
692 def PDOInfoUpdate(self): |
1000 def PDOInfoUpdate(self): |
693 """ |
1001 """ |
694 Call RequestPDOInfo method and create Choicebook |
1002 Call RequestPDOInfo method and create Choicebook |
695 """ |
1003 """ |
696 self.Controler.CommonMethod.RequestPDOInfo() |
1004 self.Controler.CommonMethod.RequestPDOInfo() |
697 self.CallPDOChoicebook.Destroy() |
1005 self.CallPDOChoicebook.Destroy() |
698 self.CallPDOChoicebook = PDOChoicebook(self, controler=self.Controler) |
1006 self.CallPDOChoicebook = PDOChoicebook(self, controler=self.Controler, name="Rx") |
699 self.Refresh() |
1007 self.Refresh() |
700 |
1008 |
701 |
1009 class TxPDOPanelClass(wx.Panel): |
702 #------------------------------------------------------------------------------- |
|
703 # For PDO Choicebook (divide Tx, Rx PDO) |
|
704 #------------------------------------------------------------------------------- |
|
705 class PDOChoicebook(wx.Choicebook): |
|
706 def __init__(self, parent, controler): |
1010 def __init__(self, parent, controler): |
707 """ |
1011 """ |
708 Constructor |
1012 Constructor |
709 @param parent: Reference to the parent PDOPanelClass class |
1013 @param parent: Reference to the parent EtherCATManagementTreebook class |
710 @param controler: _EthercatSlaveCTN class in EthercatSlave.py |
1014 @param controler: _EthercatSlaveCTN class in EthercatSlave.py |
711 """ |
1015 """ |
712 wx.Choicebook.__init__(self, parent, id=-1, size=(500, 500), style=wx.CHB_DEFAULT) |
1016 wx.Panel.__init__(self, parent, -1) |
713 self.Controler = controler |
1017 self.Controler = controler |
714 |
1018 |
715 RxWin = PDONoteBook(self, controler=self.Controler, name="Rx") |
1019 # add jblee |
716 TxWin = PDONoteBook(self, controler=self.Controler, name="Tx") |
1020 self.PDOIndexList = [] |
717 self.AddPage(RxWin, "RxPDO") |
1021 self.LoadPDOSelectData() |
718 self.AddPage(TxWin, "TxPDO") |
1022 |
719 |
1023 #HSAHN ADD. 2015.7.26 PDO Select Function ADD |
720 self.Bind(wx.EVT_CHOICEBOOK_PAGE_CHANGED, self.OnPageChanged) |
1024 self.Controler.CommonMethod.RequestPDOInfo() |
721 self.Bind(wx.EVT_CHOICEBOOK_PAGE_CHANGING, self.OnPageChanging) |
1025 self.PDOcheckBox = [] |
722 |
1026 self.tx_pdo_entries = self.Controler.CommonMethod.GetTxPDOCategory() |
723 def OnPageChanged(self, event): |
1027 if len(self.tx_pdo_entries): |
724 old = event.GetOldSelection() |
1028 for i in range(len(self.tx_pdo_entries)): |
725 new = event.GetSelection() |
1029 self.PDOcheckBox.append(wx.CheckBox(self, label=str(hex(self.tx_pdo_entries[i]['pdo_index'])), size=(120,15))) |
726 sel = self.GetSelection() |
1030 if not self.Controler.SelectedTxPDOIndex and self.tx_pdo_entries[i]['sm'] is not None: |
727 event.Skip() |
1031 self.PDOcheckBox[-1].SetValue(True) |
728 |
1032 self.Controler.SelectedTxPDOIndex.append(int(self.PDOcheckBox[-1].GetLabel(), 0)) |
729 def OnPageChanging(self, event): |
1033 self.InitSavePDO() |
730 old = event.GetOldSelection() |
1034 elif self.tx_pdo_entries[i]['pdo_index'] in self.Controler.SelectedTxPDOIndex: |
731 new = event.GetSelection() |
1035 self.PDOIndexList.append(str(hex(self.tx_pdo_entries[i]['pdo_index']))) |
732 sel = self.GetSelection() |
1036 self.PDOcheckBox[-1].SetValue(True) |
733 event.Skip() |
1037 for cb in self.PDOcheckBox: |
734 |
1038 self.Bind(wx.EVT_CHECKBOX, self.PDOSelectCheck, cb) |
|
1039 |
|
1040 self.PDOListBox = wx.StaticBox(self, label=_("PDO Mapping Select")) |
|
1041 self.PDOListBoxSizer = wx.StaticBoxSizer(self.PDOListBox, orient=wx.HORIZONTAL) |
|
1042 self.TxPDOListBox = wx.StaticBox(self, label=_("TxPDO")) |
|
1043 self.TxPDOListBoxSizer = wx.StaticBoxSizer(self.TxPDOListBox, orient=wx.VERTICAL) |
|
1044 self.TxPDOListBoxInnerSizer = wx.FlexGridSizer(cols=3, hgap=5, rows=10, vgap=5) |
|
1045 self.TxPDOListBoxInnerSizer.AddMany(self.PDOcheckBox[0:len(self.tx_pdo_entries)]) |
|
1046 self.TxPDOListBoxSizer.Add(self.TxPDOListBoxInnerSizer) |
|
1047 self.PDOListBoxSizer.Add(self.TxPDOListBoxSizer) |
|
1048 self.PDOWarningText = wx.StaticText(self, -1, |
|
1049 " *Warning*\n\n By default configuration, \n\n first mapping set is selected. \n\n Choose the PDO mapping!", |
|
1050 size=(220, -1)) |
|
1051 self.PDOListBoxSizer.Add(self.PDOWarningText) |
|
1052 |
|
1053 self.PDOMonitoringEditorMainSizer = wx.BoxSizer(wx.VERTICAL) |
|
1054 self.PDOMonitoringEditorInnerMainSizer = wx.FlexGridSizer(cols=1, hgap=10, rows=2, vgap=10) |
|
1055 |
|
1056 self.CallPDOChoicebook = PDONoteBook(self, controler=self.Controler, name="Tx") |
|
1057 self.PDOMonitoringEditorInnerMainSizer.Add(self.CallPDOChoicebook, wx.ALL) |
|
1058 |
|
1059 self.PDOInformationBox = wx.StaticBox(self, label=_("TxPDO Mapping List")) |
|
1060 self.PDOInformationBoxSizer = wx.StaticBoxSizer(self.PDOInformationBox, orient=wx.VERTICAL) |
|
1061 self.PDOInformationBoxSizer.Add(self.PDOMonitoringEditorInnerMainSizer) |
|
1062 |
|
1063 self.PDOMonitoringEditorMainSizer.Add(self.PDOListBoxSizer) |
|
1064 self.PDOMonitoringEditorMainSizer.Add(self.PDOInformationBoxSizer) |
|
1065 self.SetSizer(self.PDOMonitoringEditorMainSizer) |
|
1066 |
|
1067 # add jblee |
|
1068 self.PDOExcludeCheck() |
|
1069 else: |
|
1070 sizer = wx.FlexGridSizer(cols=1, hgap=20,rows=3, vgap=20) |
|
1071 line = wx.StaticText(self, -1, "\n This device does not support TxPDO.") |
|
1072 |
|
1073 sizer.Add(line) |
|
1074 self.SetSizer(sizer) |
|
1075 |
|
1076 def LoadPDOSelectData(self): |
|
1077 TxPDOData = self.Controler.BaseParams.getTxPDO() |
|
1078 TxPDOs = [] |
|
1079 if TxPDOData != "None": |
|
1080 TxPDOs = TxPDOData.split() |
|
1081 if TxPDOs : |
|
1082 for TxPDO in TxPDOs : |
|
1083 self.Controler.SelectedTxPDOIndex.append(int(TxPDO, 0)) |
|
1084 |
|
1085 def PDOSelectCheck(self, event): |
|
1086 # add jblee for Save User Select |
|
1087 cb = event.GetEventObject() |
|
1088 # prevent duplicated check |
|
1089 if cb.GetValue() and int(cb.GetLabel(), 0) not in self.Controler.SelectedTxPDOIndex: |
|
1090 self.Controler.SelectedTxPDOIndex.append(int(cb.GetLabel(), 0)) |
|
1091 self.PDOIndexList.append(cb.GetLabel()) |
|
1092 else: |
|
1093 self.Controler.SelectedTxPDOIndex.remove(int(cb.GetLabel(), 0)) |
|
1094 self.PDOIndexList.remove(cb.GetLabel()) |
|
1095 |
|
1096 data = "" |
|
1097 for PDOIndex in self.PDOIndexList: |
|
1098 data = data + " " + PDOIndex |
|
1099 |
|
1100 self.Controler.BaseParams.setTxPDO(data) |
|
1101 self.Controler.GetCTRoot().CTNRequestSave() |
|
1102 |
|
1103 self.PDOExcludeCheck() |
|
1104 |
|
1105 def InitSavePDO(self): |
|
1106 for PDOIndex in self.Controler.SelectedTxPDOIndex: |
|
1107 self.PDOIndexList.append(str(hex(PDOIndex))) |
|
1108 |
|
1109 data = "" |
|
1110 for PDOIndex in self.PDOIndexList: |
|
1111 data = data + " " + PDOIndex |
|
1112 |
|
1113 self.Controler.BaseParams.setTxPDO(data) |
|
1114 |
|
1115 # 2016.06.21 |
|
1116 # add jblee for check exclude pdo list |
|
1117 def PDOExcludeCheck(self): |
|
1118 CurIndexs = self.Controler.SelectedTxPDOIndex |
|
1119 for CB in self.PDOcheckBox: |
|
1120 if len(CB.GetLabel().split()) > 1: |
|
1121 CB.Enable() |
|
1122 CB.SetLabel(CB.GetLabel().split()[0]) |
|
1123 |
|
1124 for pdo in self.tx_pdo_entries: |
|
1125 for CurIndex in CurIndexs: |
|
1126 if pdo["pdo_index"] == CurIndex: |
|
1127 ex_list = pdo["exclude_list"] |
|
1128 for ex_item in ex_list: |
|
1129 for CB in self.PDOcheckBox: |
|
1130 if CB.GetLabel() == hex(ex_item): |
|
1131 CB.SetLabel(CB.GetLabel() + " (Excluded)") |
|
1132 CB.Disable() |
|
1133 |
|
1134 def PDOInfoUpdate(self): |
|
1135 """ |
|
1136 Call RequestPDOInfo method and create Choicebook |
|
1137 """ |
|
1138 self.Controler.CommonMethod.RequestPDOInfo() |
|
1139 self.CallPDOChoicebook.Destroy() |
|
1140 self.CallPDOChoicebook = PDOChoicebook(self, controler=self.Controler, name="Tx") |
|
1141 self.Refresh() |
735 |
1142 |
736 #------------------------------------------------------------------------------- |
1143 #------------------------------------------------------------------------------- |
737 # For PDO Notebook (divide PDO index) |
1144 # For PDO Notebook (divide PDO index) |
738 #------------------------------------------------------------------------------- |
1145 #------------------------------------------------------------------------------- |
739 class PDONoteBook(wx.Notebook): |
1146 class PDONoteBook(wx.Notebook): |
852 if col_idx == 0 : |
1241 if col_idx == 0 : |
853 self.SetCellValue(row_idx, col_idx, hex(self.PDOEntry[start_value][pdo_list[col_idx]])) |
1242 self.SetCellValue(row_idx, col_idx, hex(self.PDOEntry[start_value][pdo_list[col_idx]])) |
854 else : |
1243 else : |
855 self.SetCellValue(row_idx, col_idx, str(self.PDOEntry[start_value][pdo_list[col_idx]])) |
1244 self.SetCellValue(row_idx, col_idx, str(self.PDOEntry[start_value][pdo_list[col_idx]])) |
856 if col_idx != 4 : |
1245 if col_idx != 4 : |
857 self.SetCellAlignment(row_idx, col_idx, wx.ALIGN_CENTRE, wx.ALIGN_CENTRE) |
1246 self.SetCellAlignment(row_idx, col_idx, wx.ALIGN_CENTER, wx.ALIGN_CENTER) |
858 else : |
1247 else : |
859 self.SetCellAlignment(row_idx, col_idx, wx.ALIGN_LEFT, wx.ALIGN_CENTRE) |
1248 self.SetCellAlignment(row_idx, col_idx, wx.ALIGN_LEFT, wx.ALIGN_CENTER) |
860 self.SetReadOnly(row_idx, col_idx, True) |
1249 self.SetReadOnly(row_idx, col_idx, True) |
861 self.SetRowSize(row_idx, 25) |
1250 self.SetRowSize(row_idx, 25) |
862 start_value += 1 |
1251 start_value += 1 |
863 |
1252 |
|
1253 #------------------------------------------------------------------------------- |
|
1254 # For MDP Main Panel |
|
1255 #------------------------------------------------------------------------------- |
|
1256 class MDPPanel(wx.Panel): |
|
1257 def __init__(self, parent, controler): |
|
1258 """ |
|
1259 Constructor |
|
1260 @param parent: Reference to the parent EtherCATManagementTreebook class |
|
1261 @param controler: _EthercatSlaveCTN class in EthercatSlave.py |
|
1262 """ |
|
1263 wx.Panel.__init__(self, parent, -1) |
|
1264 self.parent = parent |
|
1265 self.Controler = controler |
|
1266 |
|
1267 sizer = wx.FlexGridSizer(cols=3, hgap=20, rows=1, vgap=20) |
|
1268 |
|
1269 # Include Module ListBox |
|
1270 leftInnerSizer = wx.FlexGridSizer(cols=1, hgap=10,rows=2, vgap=10) |
|
1271 # Include Add, Delete Button |
|
1272 middleInnerSizer = wx.FlexGridSizer(cols=1, hgap=10,rows=2, vgap=10) |
|
1273 # Include Slot ListBox |
|
1274 rightInnerSizer = wx.FlexGridSizer(cols=1, hgap=10,rows=2, vgap=10) |
|
1275 |
|
1276 # Get Module Name as Array |
|
1277 # MDPArray = {SlaveName, [data0, data1, ...], SlotIndexIncrement, SlotPdoIncrement} |
|
1278 # data = [ModuleName, ModuleInfo, [PDOInfo1, PDOInfo2, ...]] |
|
1279 # PDOInfo = {Index, Name, BitSize, Access, PDOMapping, SubIndex, Type} |
|
1280 slave = self.Controler.CTNParent.GetSlave(self.Controler.GetSlavePos()) |
|
1281 type_infos = slave.getType() |
|
1282 MDPArray = self.Controler.CTNParent.CTNParent.GetMDPInfos(type_infos) |
|
1283 |
|
1284 NameSet = [] |
|
1285 if MDPArray: |
|
1286 for info in MDPArray[0][1]: |
|
1287 NameSet.append(info[0]) |
|
1288 |
|
1289 # Module ListBox |
|
1290 self.ModuleLabel = wx.StaticText(self, -1, "Module") |
|
1291 self.ModuleListBox = wx.ListBox(self, size = (150, 200), choices = NameSet) |
|
1292 #self.ModuleListBox = wx.ListBox(self, size = (150, 200), choices = []) |
|
1293 self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnModuleListBoxDCClick, self.ModuleListBox) |
|
1294 |
|
1295 # Button |
|
1296 self.AddButton = wx.Button(self, label=_(" Add Module ")) |
|
1297 self.DeleteButton = wx.Button(self, label=_("Delete Module")) |
|
1298 |
|
1299 # Button Event Mapping |
|
1300 self.AddButton.Bind(wx.EVT_BUTTON, self.OnAddButton) |
|
1301 self.DeleteButton.Bind(wx.EVT_BUTTON, self.OnDeleteButton) |
|
1302 |
|
1303 # Slot ListBox |
|
1304 self.SlotLabel = wx.StaticText(self, -1, "Slot") |
|
1305 self.SlotListBox = wx.ListBox(self, size = (150, 200)) |
|
1306 self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnSlotListBoxDCClick, self.SlotListBox) |
|
1307 self.SelectModule = [] |
|
1308 |
|
1309 # Add Object Each Sizer |
|
1310 leftInnerSizer.AddMany([self.ModuleLabel, self.ModuleListBox]) |
|
1311 middleInnerSizer.Add(self.AddButton, 0, wx.TOP, 100) |
|
1312 middleInnerSizer.Add(self.DeleteButton, 0, wx.BOTTOM, 120) |
|
1313 rightInnerSizer.AddMany([self.SlotLabel, self.SlotListBox]) |
|
1314 |
|
1315 sizer.AddMany([leftInnerSizer, middleInnerSizer, rightInnerSizer]) |
|
1316 |
|
1317 self.SetSizer(sizer) |
|
1318 |
|
1319 self.InitMDPSet() |
|
1320 |
|
1321 def InitMDPSet(self): |
|
1322 files = os.listdir(self.Controler.CTNPath()) |
|
1323 filepath = os.path.join(self.Controler.CTNPath(), "DataForMDP.txt") |
|
1324 try: |
|
1325 moduleDataFile = open(filepath, 'r') |
|
1326 lines = moduleDataFile.readlines() |
|
1327 |
|
1328 for line in lines: |
|
1329 if line == "\n": |
|
1330 continue |
|
1331 module_pos = line.split()[-1] |
|
1332 name_len_limit = len(line) - len(module_pos) - 2 |
|
1333 module_name = line[0:name_len_limit] |
|
1334 |
|
1335 self.SelectModule.append((module_name, int(module_pos))) |
|
1336 |
|
1337 localModuleInfo = [] |
|
1338 count = 1 |
|
1339 for (item, pos) in self.SelectModule: |
|
1340 slotString = "Slot %d %s : " % (count, item.split()[1]) + item.split()[0] |
|
1341 localModuleInfo.append(slotString) |
|
1342 count += 1 |
|
1343 self.SlotListBox.SetItems(localModuleInfo) |
|
1344 |
|
1345 except: |
|
1346 moduleDataFile = open(filepath, 'w') |
|
1347 |
|
1348 moduleDataFile.close() |
|
1349 |
|
1350 def OnAddButton(self, event): |
|
1351 files = os.listdir(self.Controler.CTNPath()) |
|
1352 filepath = os.path.join(self.Controler.CTNPath(), "DataForMDP.txt") |
|
1353 moduleDataFile = open(filepath, 'w') |
|
1354 |
|
1355 selectNum = self.ModuleListBox.GetSelection() |
|
1356 if selectNum >= 0: |
|
1357 selectStr = self.ModuleListBox.GetString(selectNum) |
|
1358 self.SelectModule.append((selectStr, selectNum)) |
|
1359 localModuleInfo = [] |
|
1360 count = 1 |
|
1361 for (item, pos) in self.SelectModule: |
|
1362 slotString = "Slot %d %s : " % (count, item.split()[1]) + item.split()[0] |
|
1363 localModuleInfo.append(slotString) |
|
1364 count += 1 |
|
1365 self.SlotListBox.SetItems(localModuleInfo) |
|
1366 |
|
1367 moduleDataFile.close() |
|
1368 |
|
1369 def OnDeleteButton(self, event): |
|
1370 files = os.listdir(self.Controler.CTNPath()) |
|
1371 filepath = os.path.join(self.Controler.CTNPath(), "DataForMDP.txt") |
|
1372 moduleDataFile = open(filepath, 'w') |
|
1373 |
|
1374 selectNum = self.SlotListBox.GetSelection() |
|
1375 if selectNum >= 0: |
|
1376 selectStr = self.SlotListBox.GetString(selectNum) |
|
1377 self.SelectModule.pop(selectNum) |
|
1378 localModuleInfo = [] |
|
1379 count = 1 |
|
1380 for (item, pos) in self.SelectModule: |
|
1381 moduleDataFile.write(item + " " + str(pos) + "\n") |
|
1382 slotString = "Slot %d %s : " % (count, item.split()[1]) + item.split()[0] |
|
1383 localModuleInfo.append(slotString) |
|
1384 count += 1 |
|
1385 self.SlotListBox.SetItems(localModuleInfo) |
|
1386 |
|
1387 moduleDataFile.close() |
|
1388 |
|
1389 def OnModuleListBoxDCClick(self, event): |
|
1390 files = os.listdir(self.Controler.CTNPath()) |
|
1391 filepath = os.path.join(self.Controler.CTNPath(), "DataForMDP.txt") |
|
1392 moduleDataFile = open(filepath, 'w') |
|
1393 |
|
1394 selectNum = self.ModuleListBox.GetSelection() |
|
1395 if selectNum >= 0: |
|
1396 selectStr = self.ModuleListBox.GetString(selectNum) |
|
1397 self.SelectModule.append((selectStr, selectNum)) |
|
1398 localModuleInfo = [] |
|
1399 count = 1 |
|
1400 for (item, pos) in self.SelectModule: |
|
1401 moduleDataFile.write(item + " " + str(pos) + "\n") |
|
1402 slotString = "Slot %d %s : " % (count, item.split()[1]) + item.split()[0] |
|
1403 localModuleInfo.append(slotString) |
|
1404 module = self.Controler.CTNParent.CTNParent.GetSelectModule(pos) |
|
1405 self.Controler.CommonMethod.SavePDOData(module) |
|
1406 count += 1 |
|
1407 self.SlotListBox.SetItems(localModuleInfo) |
|
1408 |
|
1409 moduleDataFile.close() |
|
1410 |
|
1411 def OnSlotListBoxDCClick(self, event): |
|
1412 files = os.listdir(self.Controler.CTNPath()) |
|
1413 filepath = os.path.join(self.Controler.CTNPath(), "DataForMDP.txt") |
|
1414 moduleDataFile = open(filepath, 'w') |
|
1415 |
|
1416 selectNum = self.SlotListBox.GetSelection() |
|
1417 if selectNum >= 0: |
|
1418 selectStr = self.SlotListBox.GetString(selectNum) |
|
1419 self.SelectModule.pop(selectNum) |
|
1420 localModuleInfo = [] |
|
1421 count = 1 |
|
1422 for (item, pos) in self.SelectModule: |
|
1423 moduleDataFile.write(item + " " + str(pos) + "\n") |
|
1424 slotString = "Slot %d %s : " % (count, item.split()[1]) + item.split()[0] |
|
1425 localModuleInfo.append(slotString) |
|
1426 count += 1 |
|
1427 self.SlotListBox.SetItems(localModuleInfo) |
|
1428 |
|
1429 moduleDataFile.close() |
864 |
1430 |
865 #------------------------------------------------------------------------------- |
1431 #------------------------------------------------------------------------------- |
866 # For EEPROM Access Main Panel |
1432 # For EEPROM Access Main Panel |
867 # (This class explain EEPROM Access) |
1433 # (This class explain EEPROM Access) |
868 #------------------------------------------------------------------------------- |
1434 #------------------------------------------------------------------------------- |
1000 cnt_pdi_type = self.Controler.CommonMethod.SmartViewInfosFromXML["pdi_type"] |
1571 cnt_pdi_type = self.Controler.CommonMethod.SmartViewInfosFromXML["pdi_type"] |
1001 for i in self.PDIType.keys(): |
1572 for i in self.PDIType.keys(): |
1002 if cnt_pdi_type == i: |
1573 if cnt_pdi_type == i: |
1003 cnt_pdi_type = self.PDIType[i][0] |
1574 cnt_pdi_type = self.PDIType[i][0] |
1004 break |
1575 break |
1005 # Set Config Data |
1576 # Set Config Data |
1006 for treelist, data in [("EEPROM Size (Bytes)", |
1577 for treelist, data in [("EEPROM Size (Bytes)", |
1007 str(self.Controler.CommonMethod.SmartViewInfosFromXML["eeprom_size"])), |
1578 str(self.Controler.CommonMethod.SmartViewInfosFromXML["eeprom_size"])), |
1008 ("PDI Type", |
1579 ("PDI Type", |
1009 cnt_pdi_type), |
1580 cnt_pdi_type), |
1010 ("Device Emulation", |
1581 ("Device Emulation", |
1011 self.Controler.CommonMethod.SmartViewInfosFromXML["device_emulation"])]: |
1582 self.Controler.CommonMethod.SmartViewInfosFromXML["device_emulation"])]: |
1012 self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.ConfigData[treelist], data, 1) |
1583 self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.ConfigData[treelist], data, 1) |
1013 |
1584 |
1014 # Device Identity: Vendor ID, Product Code, Revision No., Serial No. |
1585 # Device Identity: Vendor ID, Product Code, Revision No., Serial No. |
1015 # Set Device Identity |
1586 # Set Device Identity |
1016 for treelist, data in [("Vendor ID", self.Controler.CommonMethod.SmartViewInfosFromXML["vendor_id"]), |
1587 for treelist, data in [("Vendor ID", self.Controler.CommonMethod.SmartViewInfosFromXML["vendor_id"]), |
1017 ("Product Code", self.Controler.CommonMethod.SmartViewInfosFromXML["product_code"]), |
1588 ("Product Code", self.Controler.CommonMethod.SmartViewInfosFromXML["product_code"]), |
1018 ("Revision No.", self.Controler.CommonMethod.SmartViewInfosFromXML["revision_no"]), |
1589 ("Revision No.", self.Controler.CommonMethod.SmartViewInfosFromXML["revision_no"]), |
1019 ("Serial No.", self.Controler.CommonMethod.SmartViewInfosFromXML["serial_no"])]: |
1590 ("Serial No.", self.Controler.CommonMethod.SmartViewInfosFromXML["serial_no"])]: |
1020 self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.DeviceIdentity[treelist], data, 1) |
1591 self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.DeviceIdentity[treelist], data, 1) |
1021 |
1592 |
1022 # Mailbox: Supported Mailbox, Bootstrap Configuration, Standard Configuration |
1593 # Mailbox: Supported Mailbox, Bootstrap Configuration, Standard Configuration |
1023 # Set Mailbox |
1594 # Set Mailbox |
1024 for treelist, data in [("Supported Mailbox", self.Controler.CommonMethod.SmartViewInfosFromXML["supported_mailbox"]), |
1595 for treelist, data in [("Supported Mailbox", self.Controler.CommonMethod.SmartViewInfosFromXML["supported_mailbox"]), |
1025 ("Bootstrap Configuration", ""), |
1596 ("Bootstrap Configuration", ""), |
1026 ("Standard Configuration", "")]: |
1597 ("Standard Configuration", "")]: |
1027 self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.Mailbox[treelist], data, 1) |
1598 self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.Mailbox[treelist], data, 1) |
1028 # Set Bootstrap Configuration: Receive Offset, Receive Size, Send Offset, Send Size |
1599 # Set Bootstrap Configuration: Receive Offset, Receive Size, Send Offset, Send Size |
1029 for treelist, data in [("Receive Offset", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_bootstrapconf_outstart"]), |
1600 for treelist, data in [("Receive Offset", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_bootstrapconf_outstart"]), |
1030 ("Receive Size", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_bootstrapconf_outlength"]), |
1601 ("Receive Size", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_bootstrapconf_outlength"]), |
1031 ("Send Offset", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_bootstrapconf_instart"]), |
1602 ("Send Offset", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_bootstrapconf_instart"]), |
1032 ("Send Size", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_bootstrapconf_inlength"])]: |
1603 ("Send Size", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_bootstrapconf_inlength"])]: |
1033 self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.BootstrapConfig[treelist], data, 1) |
1604 self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.BootstrapConfig[treelist], data, 1) |
1034 # Set Standard Configuration: Receive Offset, Receive Size, Send Offset, Send Size |
1605 # Set Standard Configuration: Receive Offset, Receive Size, Send Offset, Send Size |
1035 for treelist, data in [("Receive Offset", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_standardconf_outstart"]), |
1606 for treelist, data in [("Receive Offset", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_standardconf_outstart"]), |
1036 ("Receive Size", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_standardconf_outlength"]), |
1607 ("Receive Size", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_standardconf_outlength"]), |
1037 ("Send Offset", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_standardconf_instart"]), |
1608 ("Send Offset", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_standardconf_instart"]), |
1038 ("Send Size", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_standardconf_inlength"])]: |
1609 ("Send Size", self.Controler.CommonMethod.SmartViewInfosFromXML["mailbox_standardconf_inlength"])]: |
1039 self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.StandardConfig[treelist], data, 1) |
1610 self.TreeListCtrl.Tree.SetItemText(self.TreeListCtrl.StandardConfig[treelist], data, 1) |
1040 |
1611 |
1041 def SetEEPROMData(self): |
1612 def SetEEPROMData(self): |
1042 """ |
1613 """ |
1043 Set data based on slave EEPROM. |
1614 Set data based on slave EEPROM. |
1044 """ |
1615 """ |
1045 # sii_dict = { Parameter : (WordAddress, WordSize) } |
|
1046 sii_dict= { 'PDIControl' : ( '0', 1), |
1616 sii_dict= { 'PDIControl' : ( '0', 1), |
1047 'PDIConfiguration' : ( '1', 1), |
1617 'PDIConfiguration' : ( '1', 1), |
1048 'PulseLengthOfSYNCSignals' : ( '2', 1), |
1618 'PulseLengthOfSYNCSignals' : ( '2', 1), |
1049 'ExtendedPDIConfiguration' : ( '3', 1), |
1619 'ExtendedPDIConfiguration' : ( '3', 1), |
1050 'ConfiguredStationAlias' : ( '4', 1), |
1620 'ConfiguredStationAlias' : ( '4', 1), |
2097 class MasterStatePanelClass(wx.Panel): |
2653 class MasterStatePanelClass(wx.Panel): |
2098 def __init__(self, parent, controler): |
2654 def __init__(self, parent, controler): |
2099 """ |
2655 """ |
2100 Constructor |
2656 Constructor |
2101 @param parent: wx.ScrollWindow object |
2657 @param parent: wx.ScrollWindow object |
2102 @Param controler: _EthercatSlaveCTN class in EthercatSlave.py |
2658 @Param controler: _EthercatCTN class in EthercatMaster.py |
2103 """ |
2659 """ |
2104 wx.Panel.__init__(self, parent, -1, (0, 0), |
2660 wx.Panel.__init__(self, parent) |
2105 size=wx.DefaultSize, style = wx.SUNKEN_BORDER) |
|
2106 self.Controler = controler |
2661 self.Controler = controler |
2107 self.parent = parent |
2662 self.parent = parent |
2108 self.StaticBox = {} |
2663 self.StaticBox = {} |
2109 self.StaticText = {} |
2664 self.StaticText = {} |
2110 self.TextCtrl = {} |
2665 self.TextCtrl = {} |
2111 |
2666 |
2112 # ----------------------- Main Sizer and Update Button -------------------------------------------- |
2667 # ---------------------------- Main Sizer and Buttons -------------------------------------------- |
2113 self.MasterStateSizer = {"main" : wx.BoxSizer(wx.VERTICAL)} |
2668 self.MasterStateSizer = {"main" : wx.BoxSizer(wx.VERTICAL)} |
2114 for key, attr in [ |
2669 for key, attr in [ |
2115 ("innerMain", [1, 10, 2, 10]), |
2670 ("innerTop", [2, 10, 1, 10]), |
2116 ("innerTopHalf", [2, 10, 1, 10]), |
2671 ("innerMiddle", [1, 10, 1, 10]), |
2117 ("innerBottomHalf", [2, 10, 1, 10]), |
2672 ("innerBottom", [1, 10, 1, 10]), |
2118 ("innerMasterState", [2, 10, 3, 10]), |
2673 ("innerMasterState", [2, 10, 3, 10]), |
2119 ("innerDeviceInfo", [4, 10, 3, 10]), |
2674 ("innerDeviceInfo", [4, 10, 3, 10]), |
2120 ("innerFrameInfo", [4, 10, 5, 10])]: |
2675 ("innerFrameInfo", [4, 10, 5, 10]), |
|
2676 ("innerSlaveInfo", [1, 10, 2, 10])]: |
2121 self.MasterStateSizer[key] = wx.FlexGridSizer(cols=attr[0], hgap=attr[1], rows=attr[2], vgap=attr[3]) |
2677 self.MasterStateSizer[key] = wx.FlexGridSizer(cols=attr[0], hgap=attr[1], rows=attr[2], vgap=attr[3]) |
2122 |
2678 |
2123 |
2679 self.MSUpdateButton = wx.Button(self, label=_("Update")) |
2124 self.UpdateButton = wx.Button(self, label=_('Update')) |
2680 self.MSUpdateButton.Bind(wx.EVT_BUTTON, self.OnMSUpdateButtonClick) |
2125 self.UpdateButton.Bind(wx.EVT_BUTTON, self.OnButtonClick) |
2681 self.SIUpdateButton = wx.Button(self, label=_("Update")) |
2126 |
2682 self.SIUpdateButton.Bind(wx.EVT_BUTTON, self.OnSIUpdateButtonClick) |
|
2683 |
2127 for key, label in [ |
2684 for key, label in [ |
2128 ('masterState', 'EtherCAT Master State'), |
2685 ("masterState", "EtherCAT Master State"), |
2129 ('deviceInfo', 'Ethernet Network Card Information'), |
2686 ("deviceInfo", "Ethernet Network Card Information"), |
2130 ('frameInfo', 'Network Frame Information')]: |
2687 ("frameInfo", "Network Frame Information"), |
|
2688 ("slaveInfo", "Slave Information")]: |
2131 self.StaticBox[key] = wx.StaticBox(self, label=_(label)) |
2689 self.StaticBox[key] = wx.StaticBox(self, label=_(label)) |
2132 self.MasterStateSizer[key] = wx.StaticBoxSizer(self.StaticBox[key]) |
2690 self.MasterStateSizer[key] = wx.StaticBoxSizer(self.StaticBox[key]) |
2133 |
2691 |
2134 |
|
2135 # ----------------------- Master State ----------------------------------------------------------- |
2692 # ----------------------- Master State ----------------------------------------------------------- |
2136 for key, label in [ |
2693 for key, label in [ |
2137 ('Phase', 'Phase:'), |
2694 ("Phase", "Phase:"), |
2138 ('Active', 'Active:'), |
2695 ("Active", "Active:"), |
2139 ('Slaves', 'Slave Count:')]: |
2696 ("Slaves", "Slave Count:")]: |
2140 self.StaticText[key] = wx.StaticText(self, label=_(label)) |
2697 self.StaticText[key] = wx.StaticText(self, label=_(label)) |
2141 self.TextCtrl[key] = wx.TextCtrl(self, size=wx.Size(130, 24), style=wx.TE_READONLY) |
2698 self.TextCtrl[key] = wx.TextCtrl(self, size=wx.Size(130, 24), style=wx.TE_READONLY) |
2142 self.MasterStateSizer['innerMasterState'].AddMany([self.StaticText[key], self.TextCtrl[key]]) |
2699 self.MasterStateSizer["innerMasterState"].AddMany([self.StaticText[key], self.TextCtrl[key]]) |
2143 |
2700 |
2144 self.MasterStateSizer['masterState'].AddSizer(self.MasterStateSizer['innerMasterState']) |
2701 self.MasterStateSizer["masterState"].AddSizer(self.MasterStateSizer["innerMasterState"]) |
2145 |
2702 |
2146 # ----------------------- Ethernet Network Card Information --------------------------------------- |
2703 # ----------------------- Ethernet Network Card Information --------------------------------------- |
2147 for key, label in [ |
2704 for key, label in [ |
2148 ('Main', 'MAC Address:'), |
2705 ("Main", "MAC Address:"), |
2149 ('Link', 'Link State:'), |
2706 ("Link", "Link State:"), |
2150 ('Tx frames', 'Tx Frames:'), |
2707 ("Tx frames", "Tx Frames:"), |
2151 ('Rx frames', 'Rx Frames:'), |
2708 ("Rx frames", "Rx Frames:"), |
2152 ('Lost frames', 'Lost Frames:')]: |
2709 ("Lost frames", "Lost Frames:")]: |
2153 self.StaticText[key] = wx.StaticText(self, label=_(label)) |
2710 self.StaticText[key] = wx.StaticText(self, label=_(label)) |
2154 self.TextCtrl[key] = wx.TextCtrl(self, size=wx.Size(130, 24), style=wx.TE_READONLY) |
2711 self.TextCtrl[key] = wx.TextCtrl(self, size=wx.Size(130, 24), style=wx.TE_READONLY) |
2155 self.MasterStateSizer['innerDeviceInfo'].AddMany([self.StaticText[key], self.TextCtrl[key]]) |
2712 self.MasterStateSizer["innerDeviceInfo"].AddMany([self.StaticText[key], self.TextCtrl[key]]) |
2156 |
2713 |
2157 self.MasterStateSizer['deviceInfo'].AddSizer(self.MasterStateSizer['innerDeviceInfo']) |
2714 self.MasterStateSizer["deviceInfo"].AddSizer(self.MasterStateSizer["innerDeviceInfo"]) |
2158 |
2715 |
2159 # ----------------------- Network Frame Information ----------------------------------------------- |
2716 # ----------------------- Network Frame Information ----------------------------------------------- |
2160 for key, label in [ |
2717 for key, label in [ |
2161 ('Tx frame rate [1/s]', 'Tx Frame Rate [1/s]:'), |
2718 ("Tx frame rate [1/s]", "Tx Frame Rate [1/s]:"), |
2162 ('Rx frame rate [1/s]', 'Tx Rate [kByte/s]:'), |
2719 ("Tx rate [KByte/s]", "Tx Rate [KByte/s]:"), |
2163 ('Loss rate [1/s]', 'Loss Rate [1/s]:'), |
2720 ("Rx frame rate [1/s]", "Rx Frame Rate [1/s]:"), |
2164 ('Frame loss [%]', 'Frame Loss [%]:')]: |
2721 ("Rx rate [KByte/s]", "Rx Rate [KByte/s]:"), |
|
2722 ("Loss rate [1/s]", "Loss Rate [1/s]:"), |
|
2723 ("Frame loss [%]", "Frame Loss [%]:")]: |
2165 self.StaticText[key] = wx.StaticText(self, label=_(label)) |
2724 self.StaticText[key] = wx.StaticText(self, label=_(label)) |
2166 self.MasterStateSizer['innerFrameInfo'].Add(self.StaticText[key]) |
2725 self.MasterStateSizer["innerFrameInfo"].Add(self.StaticText[key]) |
2167 self.TextCtrl[key] = {} |
2726 self.TextCtrl[key] = {} |
2168 for index in ['0', '1', '2']: |
2727 for index in ["0", "1", "2"]: |
2169 self.TextCtrl[key][index] = wx.TextCtrl(self, size=wx.Size(130, 24), style=wx.TE_READONLY) |
2728 self.TextCtrl[key][index] = wx.TextCtrl(self, size=wx.Size(130, 24), style=wx.TE_READONLY) |
2170 self.MasterStateSizer['innerFrameInfo'].Add(self.TextCtrl[key][index]) |
2729 self.MasterStateSizer["innerFrameInfo"].Add(self.TextCtrl[key][index]) |
2171 |
2730 |
2172 self.MasterStateSizer['frameInfo'].AddSizer(self.MasterStateSizer['innerFrameInfo']) |
2731 self.MasterStateSizer["frameInfo"].AddSizer(self.MasterStateSizer["innerFrameInfo"]) |
2173 |
2732 |
|
2733 # ------------------------------- Slave Information ----------------------------------------------- |
|
2734 self.SITreeListCtrl = SITreeListCtrl(self, self.Controler) |
|
2735 self.MasterStateSizer["innerSlaveInfo"].AddMany([self.SIUpdateButton, |
|
2736 self.SITreeListCtrl]) |
|
2737 self.MasterStateSizer["slaveInfo"].AddSizer( |
|
2738 self.MasterStateSizer["innerSlaveInfo"]) |
|
2739 |
2174 # --------------------------------- Main Sizer ---------------------------------------------------- |
2740 # --------------------------------- Main Sizer ---------------------------------------------------- |
|
2741 self.MasterStateSizer["main"].Add(self.MSUpdateButton) |
2175 for key, sub, in [ |
2742 for key, sub, in [ |
2176 ('innerTopHalf', [ |
2743 ("innerTop", [ |
2177 'masterState', 'deviceInfo']), |
2744 "masterState", "deviceInfo"]), |
2178 ('innerBottomHalf', [ |
2745 ("innerMiddle", [ |
2179 'frameInfo']), |
2746 "frameInfo"]), |
2180 ('innerMain', [ |
2747 ("innerBottom", [ |
2181 'innerTopHalf', 'innerBottomHalf'])]: |
2748 "slaveInfo"]), |
|
2749 ("main", [ |
|
2750 "innerTop", "innerMiddle", "innerBottom"])]: |
2182 for key2 in sub: |
2751 for key2 in sub: |
2183 self.MasterStateSizer[key].AddSizer(self.MasterStateSizer[key2]) |
2752 self.MasterStateSizer[key].AddSizer(self.MasterStateSizer[key2]) |
2184 |
2753 |
2185 self.MasterStateSizer['main'].AddSizer(self.UpdateButton) |
2754 self.SetSizer(self.MasterStateSizer["main"]) |
2186 self.MasterStateSizer['main'].AddSizer(self.MasterStateSizer['innerMain']) |
2755 |
2187 |
2756 def OnMSUpdateButtonClick(self, event): |
2188 self.SetSizer(self.MasterStateSizer['main']) |
2757 """ |
2189 |
2758 Handle the event of the "Update" button. |
2190 def OnButtonClick(self, event): |
|
2191 """ |
|
2192 Handle the event of the 'Update' button. |
|
2193 Update the data of the master state. |
2759 Update the data of the master state. |
2194 @param event: wx.EVT_BUTTON object |
2760 @param event: wx.EVT_BUTTON object |
2195 """ |
2761 """ |
2196 if self.Controler.GetCTRoot()._connector is not None: |
2762 if self.Controler.GetCTRoot()._connector is not None: |
2197 self.MasterState = self.Controler.CommonMethod.GetMasterState() |
2763 self.MasterState = self.Controler.CommonMethod.GetMasterState() |
2201 if isinstance(self.TextCtrl[key], dict): |
2767 if isinstance(self.TextCtrl[key], dict): |
2202 for index in self.TextCtrl[key]: |
2768 for index in self.TextCtrl[key]: |
2203 self.TextCtrl[key][index].SetValue(self.MasterState[key][int(index)]) |
2769 self.TextCtrl[key][index].SetValue(self.MasterState[key][int(index)]) |
2204 else: |
2770 else: |
2205 self.TextCtrl[key].SetValue(self.MasterState[key][0]) |
2771 self.TextCtrl[key].SetValue(self.MasterState[key][0]) |
|
2772 |
2206 else : |
2773 else : |
2207 self.Controler.CommonMethod.CreateErrorDialog('PLC not connected!') |
2774 self.Controler.CommonMethod.CreateErrorDialog('PLC not connected!') |
|
2775 |
|
2776 def OnSIUpdateButtonClick(self, event): |
|
2777 """ |
|
2778 Handle the event of the radio box in the slave information |
|
2779 @param event: wx.EVT_RADIOBOX object |
|
2780 """ |
|
2781 if self.Controler.GetCTRoot()._connector is not None: |
|
2782 self.SITreeListCtrl.UpdateSI() |
|
2783 |
|
2784 else : |
|
2785 self.Controler.CommonMethod.CreateErrorDialog('PLC not connected!') |
|
2786 |
|
2787 |
|
2788 #------------------------------------------------------------------------------- |
|
2789 # For Slave Information Panel |
|
2790 #------------------------------------------------------------------------------- |
|
2791 class SITreeListCtrl(wx.Panel): |
|
2792 |
|
2793 EC_Addrs = ["0x0300", "0x0302", "0x0304", "0x0306", "0x0301", "0x0303", "0x0305", |
|
2794 "0x0307", "0x0308", "0x0309", "0x030A", "0x030B", "0x030C", "0x030D", |
|
2795 "0x0310", "0x0311", "0x0312", "0x0313", "0x0442", "0x0443"] |
|
2796 |
|
2797 def __init__(self, parent, controler): |
|
2798 """ |
|
2799 Constructor |
|
2800 @param parent: Reference to the MasterStatePanel class |
|
2801 @param Controler: _EthercatCTN class in EthercatMaster.py |
|
2802 """ |
|
2803 |
|
2804 wx.Panel.__init__(self, parent, -1, size=wx.Size(750, 350)) |
|
2805 |
|
2806 self.Controler=controler |
|
2807 |
|
2808 self.Tree = wx.gizmos.TreeListCtrl(self, -1, size=wx.Size(750,350), |
|
2809 style=wx.TR_HAS_BUTTONS |
|
2810 |wx.TR_HIDE_ROOT |
|
2811 |wx.TR_ROW_LINES |
|
2812 |wx.TR_COLUMN_LINES |
|
2813 |wx.TR_FULL_ROW_HIGHLIGHT) |
|
2814 for label, width in [ |
|
2815 ("name", 400), |
|
2816 ("position", 100), |
|
2817 ("state", 100), |
|
2818 ("error", 100)]: |
|
2819 self.Tree.AddColumn(label, width=width) |
|
2820 |
|
2821 self.Tree.SetMainColumn(0) |
|
2822 |
|
2823 def UpdateSI(self): |
|
2824 """ |
|
2825 Update the data of the slave information. |
|
2826 """ |
|
2827 position, not_used, state, not_used, name = range(5) |
|
2828 |
|
2829 slave_node = [] |
|
2830 slave_info_list = [] |
|
2831 error_counter= [] |
|
2832 |
|
2833 # get slave informations (name, position, state) |
|
2834 slaves_infos = self.Controler.CommonMethod.GetSlaveStateFromSlave() |
|
2835 slave_info_lines = slaves_infos.splitlines() |
|
2836 |
|
2837 for line in slave_info_lines: |
|
2838 slave_info_list.append(line.split(None,4)) |
|
2839 |
|
2840 slave_num = len(slave_info_lines) |
|
2841 |
|
2842 reg_info = [] |
|
2843 for ec in self.EC_Addrs: |
|
2844 reg_info.append(ec + ",0x001") |
|
2845 |
|
2846 # get error counts of slaves |
|
2847 err_count_list = self.Controler.CommonMethod.MultiRegRead(slave_num, reg_info) |
|
2848 |
|
2849 self.Tree.DeleteAllItems() |
|
2850 |
|
2851 root = self.Tree.AddRoot("") |
|
2852 ec_list_idx = 0 |
|
2853 |
|
2854 for slave_idx in range(slave_num): |
|
2855 slave_node = self.Tree.AppendItem(root, "") |
|
2856 |
|
2857 # set name, postion, state |
|
2858 col_num = 0 |
|
2859 for info_idx in [name, position, state]: |
|
2860 self.Tree.SetItemText(slave_node, |
|
2861 slave_info_list[slave_idx][info_idx], col_num) |
|
2862 col_num += 1 |
|
2863 |
|
2864 error_counter = {} |
|
2865 ec_idx = 0 |
|
2866 |
|
2867 # set error counter's name and default value |
|
2868 for ec, sub_ecs in [("Port Error Counters 0/1/2/3",[ |
|
2869 "Invaild Frame Counter 0/1/2/3", |
|
2870 "RX Error Counter 0/1/2/3"]), |
|
2871 ("Forward RX Error Counter 0/1/2/3", []), |
|
2872 ("ECAT Processing Unit Error Counter", []), |
|
2873 ("PDI Error Counter", []), |
|
2874 ("Lost Link Counter 0/1/2/3", []), |
|
2875 ("Watchdog Counter Process Data", []), |
|
2876 ("Watchdog Counter PDI", [])]: |
|
2877 ec_sub_idx = 0 |
|
2878 ec_name = ec |
|
2879 tree_node = self.Tree.AppendItem(slave_node, "%s" % ec) |
|
2880 |
|
2881 if ec_name.find("0/1/2/3") > 0: |
|
2882 num_ports = 4 |
|
2883 err_count = [0, 0, 0, 0] |
|
2884 else: |
|
2885 num_ports = 1 |
|
2886 err_count = [0] |
|
2887 |
|
2888 error_counter[(ec_idx, ec_sub_idx)] = { |
|
2889 "name": ec_name, |
|
2890 "tree_node": tree_node, |
|
2891 "num_ports": num_ports, |
|
2892 "err_count": err_count} |
|
2893 |
|
2894 for sub_ec in sub_ecs: |
|
2895 ec_sub_idx += 1 |
|
2896 ec_name = sub_ec |
|
2897 tree_node = self.Tree.AppendItem(\ |
|
2898 error_counter[(ec_idx, 0)]["tree_node"], |
|
2899 "%s" % sub_ec) |
|
2900 |
|
2901 if ec_name.find("0/1/2/3") > 0: |
|
2902 num_ports = 4 |
|
2903 err_count = [0, 0, 0, 0] |
|
2904 else: |
|
2905 num_ports = 1 |
|
2906 err_count = [0] |
|
2907 |
|
2908 error_counter[(ec_idx, ec_sub_idx)] = { |
|
2909 "name": ec_name, |
|
2910 "tree_node": tree_node, |
|
2911 "num_ports": num_ports, |
|
2912 "err_count": err_count} |
|
2913 |
|
2914 for port_num in range(num_ports): |
|
2915 try: |
|
2916 error_counter[(ec_idx, ec_sub_idx)]["err_count"][port_num] += \ |
|
2917 int(err_count_list[ec_list_idx].split(",")[2], 16) |
|
2918 except: |
|
2919 error_counter[(ec_idx, ec_sub_idx)]["err_count"][port_num] = -1 |
|
2920 |
|
2921 ec_list_idx += 1 |
|
2922 |
|
2923 if ec_sub_idx > 0: |
|
2924 for port_num in range(num_ports): |
|
2925 err_sum = 0 |
|
2926 for sub_idx in range(1, ec_sub_idx+1): |
|
2927 err_sum += error_counter[(ec_idx, sub_idx)]\ |
|
2928 ["err_count"][port_num] |
|
2929 error_counter[(ec_idx, 0)]["err_count"][port_num] = err_sum |
|
2930 |
|
2931 else: |
|
2932 for port_num in range(num_ports): |
|
2933 try: |
|
2934 error_counter[(ec_idx, ec_sub_idx)]["err_count"][port_num] += \ |
|
2935 int(err_count_list[ec_list_idx].split(",")[2], 16) |
|
2936 except: |
|
2937 error_counter[(ec_idx, ec_sub_idx)]["err_count"][port_num] = -1 |
|
2938 ec_list_idx += 1 |
|
2939 |
|
2940 ec_idx += 1 |
|
2941 |
|
2942 # set texts in "error" column. |
|
2943 ec_info_list = error_counter.items() |
|
2944 ec_info_list.sort() |
|
2945 |
|
2946 err_checker = "none" |
|
2947 |
|
2948 for (idx, sub_idx), ec_info in ec_info_list: |
|
2949 ec_text = "" |
|
2950 for port_num in range(ec_info["num_ports"]): |
|
2951 if ec_info["err_count"][port_num] != 0: |
|
2952 err_checker = "occurred" |
|
2953 |
|
2954 if ec_info["err_count"][port_num] < 0: |
|
2955 ec_text = "reg I/O error" |
|
2956 else: |
|
2957 ec_text = ec_text + "%d/" % ec_info["err_count"][port_num] |
|
2958 |
|
2959 ec_text = ec_text.strip("/") |
|
2960 |
|
2961 self.Tree.SetItemText(ec_info["tree_node"], ec_text, col_num) |
|
2962 |
|
2963 self.Tree.SetItemText(slave_node, err_checker, col_num) |
|
2964 |
|
2965 class DCConfigPanel(wx.Panel): |
|
2966 def __init__(self, parent, controler): |
|
2967 """ |
|
2968 Constructor |
|
2969 @param parent: Reference to the MasterStatePanel class |
|
2970 @param Controler: _EthercatCTN class in EthercatMaster.py |
|
2971 """ |
|
2972 |
|
2973 wx.Panel.__init__(self, parent, -1, size=wx.Size(750, 350)) |
|
2974 |
|
2975 self.Controler = controler |
|
2976 self.parent = parent |
|
2977 |
|
2978 self.ESI_DC_Data = self.Controler.CommonMethod.LoadESIData() |
|
2979 |
|
2980 # initialize SlaveStatePanel UI dictionaries |
|
2981 self.StaticBoxDic = {} |
|
2982 self.StaticTextDic = {} |
|
2983 self.TextCtrlDic = {} |
|
2984 self.ComboBoxDic = {} |
|
2985 self.CheckBoxDic = {} |
|
2986 self.RadioButtonDic = {} |
|
2987 OperationModeComboList = [] |
|
2988 Sync1CycleComboList = [] |
|
2989 |
|
2990 for ESI_Data in self.ESI_DC_Data: |
|
2991 OperationModeComboList.append(ESI_Data["desc"]) |
|
2992 |
|
2993 UnitComboList = [ "/100", "/ 50", "/ 40", "/ 30", "/ 25", "/ 20", "/16", |
|
2994 "/ 10", "/ 8", "/ 5", "/ 4", "/ 3", "/ 2", "x 1", "x 2", "x 3", "x 4", |
|
2995 "x 5", "x 8", "x 10", "x 16", "x 20", "x 25", "x 30", "x 40", "x 50", |
|
2996 "x 100" |
|
2997 ] |
|
2998 |
|
2999 UnitComboListPlus = [ "/100", "/ 50", "/ 40", "/ 30", "/ 25", "/ 20", "/16", |
|
3000 "/ 10", "/ 8", "/ 5", "/ 4", "/ 3", "/ 2", "x 0", "x 1", "x 2", "x 3", |
|
3001 "x 4", "x 5", "x 8", "x 10", "x 16", "x 20", "x 25", "x 30", "x 40", |
|
3002 "x 50", "x 100" |
|
3003 ] |
|
3004 |
|
3005 for i in range(1024): |
|
3006 Sync1CycleComboList.append("x " + str(i + 1)) |
|
3007 |
|
3008 # iniitalize BoxSizer and FlexGridSizer |
|
3009 self.SizerDic = { |
|
3010 "DCConfig_main_sizer" : wx.BoxSizer(wx.VERTICAL), |
|
3011 "DCConfig_inner_main_sizer" : wx.FlexGridSizer(cols=1, hgap=50, rows=2, vgap=10), |
|
3012 "CyclicMode_InnerSizer" : wx.FlexGridSizer(cols=1, hgap=5, rows=2, vgap=5), |
|
3013 "SyncMode_InnerSizer" : wx.FlexGridSizer(cols=2, hgap=5, rows=1, vgap=5), |
|
3014 "OperationMode_InnerSizer" : wx.FlexGridSizer(cols=2, hgap=100, rows=2, vgap=10), |
|
3015 "CheckEnable_InnerSizer" : wx.FlexGridSizer(cols=2, hgap=10, rows=1, vgap=10), |
|
3016 "Sync0_InnerSizer" : wx.FlexGridSizer(cols=1, hgap=15, rows=3, vgap=10), |
|
3017 "Sync0_CycleTimeSizer" : wx.FlexGridSizer(cols=2, hgap=10, rows=2, vgap=5), |
|
3018 "Sync0_ShiftTimeSizer" : wx.FlexGridSizer(cols=2, hgap=20, rows=2, vgap=5), |
|
3019 "Sync1_InnerSizer" : wx.FlexGridSizer(cols=1, hgap=15, rows=3, vgap=10), |
|
3020 "Sync1_CycleTimeSizer" : wx.FlexGridSizer(cols=2, hgap=10, rows=2, vgap=5), |
|
3021 "Sync1_ShiftTimeSizer" : wx.FlexGridSizer(cols=2, hgap=20, rows=2, vgap=5) |
|
3022 } |
|
3023 |
|
3024 # initialize StaticBox and StaticBoxSizer |
|
3025 for box_name, box_label in [ |
|
3026 ("CyclicModeBox", "Cyclic Mode"), |
|
3027 ("Sync0Box", "Sync0"), |
|
3028 ("Sync0CycleTimeBox", "Cycle Time (us):"), |
|
3029 ("Sync0ShiftTimeBox", "Shift Time (us):"), |
|
3030 ("Sync1Box", "Sync1"), |
|
3031 ("Sync1CycleTimeBox", "Cycle Time (us):"), |
|
3032 ("Sync1ShiftTimeBox", "Shift Time (us):") |
|
3033 ]: |
|
3034 self.StaticBoxDic[box_name] = wx.StaticBox(self, label=_(box_label)) |
|
3035 self.SizerDic[box_name] = wx.StaticBoxSizer(self.StaticBoxDic[box_name]) |
|
3036 |
|
3037 for statictext_name, statictext_label in [ |
|
3038 ("MainLabel", "Distributed Clock"), |
|
3039 ("OperationModeLabel", "Operation Mode:"), |
|
3040 ("SyncUnitCycleLabel", "Sync Unit Cycle (us)"), |
|
3041 ("Sync0ShiftTimeUserDefinedLabel", "User Defined"), |
|
3042 ("Sync1ShiftTimeUserDefinedLabel", "User Defined"), |
|
3043 ("BlankObject", ""), |
|
3044 ("BlankObject1", "") |
|
3045 ]: |
|
3046 self.StaticTextDic[statictext_name] = wx.StaticText(self, label=_(statictext_label)) |
|
3047 |
|
3048 for textctl_name in [ |
|
3049 ("SyncUnitCycle_Ctl"), |
|
3050 ("Sync0CycleTimeUserDefined_Ctl"), |
|
3051 ("Sync0ShiftTimeUserDefined_Ctl"), |
|
3052 ("Sync1CycleTimeUserDefined_Ctl"), |
|
3053 ("Sync1ShiftTimeUserDefined_Ctl"), |
|
3054 ]: |
|
3055 self.TextCtrlDic[textctl_name] = wx.TextCtrl( |
|
3056 self, size=wx.Size(130, 24), style=wx.TE_READONLY) |
|
3057 |
|
3058 for checkbox_name, checkbox_label in [ |
|
3059 ("DCEnable", "Enable"), |
|
3060 ("Sync0Enable", "Enable Sync0"), |
|
3061 ("Sync1Enable", "Enable Sync1") |
|
3062 ]: |
|
3063 self.CheckBoxDic[checkbox_name] = wx.CheckBox(self, -1, checkbox_label) |
|
3064 |
|
3065 for combobox_name, combobox_list, size in [ |
|
3066 ("OperationModeChoice", OperationModeComboList, 250), |
|
3067 ("Sync0UnitCycleChoice", UnitComboList, 130), |
|
3068 ("Sync1UnitCycleChoice", UnitComboList, 130) |
|
3069 ]: |
|
3070 self.ComboBoxDic[combobox_name] = wx.ComboBox(self, size=wx.Size(size, 24), |
|
3071 choices = combobox_list, style = wx.CB_DROPDOWN | wx.CB_READONLY) |
|
3072 |
|
3073 for radiobutton_name, radiobutton_label in [ |
|
3074 ("Sync0CycleTimeUnitRadioButton", "Sync Unit Cycle"), |
|
3075 ("Sync0CycleTimeUserDefinedRadioButton", "User Defined"), |
|
3076 ("Sync1CycleTimeUnitRadioButton", "Sync Unit Cycle"), |
|
3077 ("Sync1CycleTimeUserDefinedRadioButton", "User Defined") |
|
3078 ]: |
|
3079 self.RadioButtonDic[radiobutton_name] = wx.RadioButton( |
|
3080 self, label = radiobutton_label, style = wx.RB_SINGLE) |
|
3081 |
|
3082 |
|
3083 self.ApplyButton = wx.Button(self, label="Apply") |
|
3084 |
|
3085 # binding event |
|
3086 self.Bind(wx.EVT_CHECKBOX, self.CheckDCEnable, self.CheckBoxDic["DCEnable"]) |
|
3087 #self.Bind(wx.EVT_COMBOBOX, self.SelectOperationMode, self.ComboBoxDic["OperationModeChoice"]) |
|
3088 #self.Bind(wx.EVT_COMBOBOX, self.SelectUnitCycle, self.ComboBoxDic["Sync0UnitChoice"]) |
|
3089 self.Bind(wx.EVT_RADIOBUTTON, self.SelectSync0CycleTime, |
|
3090 self.RadioButtonDic["Sync0CycleTimeUnitRadioButton"]) |
|
3091 self.Bind(wx.EVT_RADIOBUTTON, self.SelectSync0CycleTime, |
|
3092 self.RadioButtonDic["Sync0CycleTimeUserDefinedRadioButton"]) |
|
3093 self.Bind(wx.EVT_RADIOBUTTON, self.SelectSync1CycleTime, |
|
3094 self.RadioButtonDic["Sync1CycleTimeUnitRadioButton"]) |
|
3095 self.Bind(wx.EVT_RADIOBUTTON, self.SelectSync1CycleTime, |
|
3096 self.RadioButtonDic["Sync1CycleTimeUserDefinedRadioButton"]) |
|
3097 self.Bind(wx.EVT_CHECKBOX, self.CheckSync0Enable, self.CheckBoxDic["Sync0Enable"]) |
|
3098 self.Bind(wx.EVT_CHECKBOX, self.CheckSync1Enable, self.CheckBoxDic["Sync1Enable"]) |
|
3099 self.Bind(wx.EVT_BUTTON, self.OnClickApplyButton, self.ApplyButton) |
|
3100 |
|
3101 # sync1 shifttime box contents |
|
3102 self.SizerDic["Sync1_ShiftTimeSizer"].AddMany([ |
|
3103 self.StaticTextDic["Sync1ShiftTimeUserDefinedLabel"], |
|
3104 self.TextCtrlDic["Sync1ShiftTimeUserDefined_Ctl"] |
|
3105 ]) |
|
3106 |
|
3107 # sync1 shifttime box |
|
3108 self.SizerDic["Sync1ShiftTimeBox"].Add(self.SizerDic["Sync1_ShiftTimeSizer"]) |
|
3109 |
|
3110 # sync1 cycletime box contents |
|
3111 self.SizerDic["Sync1_CycleTimeSizer"].AddMany([ |
|
3112 self.RadioButtonDic["Sync1CycleTimeUnitRadioButton"], |
|
3113 self.ComboBoxDic["Sync1UnitCycleChoice"], |
|
3114 self.RadioButtonDic["Sync1CycleTimeUserDefinedRadioButton"], |
|
3115 self.TextCtrlDic["Sync1CycleTimeUserDefined_Ctl"] |
|
3116 ]) |
|
3117 |
|
3118 # sync0 cycletime box |
|
3119 self.SizerDic["Sync1CycleTimeBox"].Add(self.SizerDic["Sync1_CycleTimeSizer"]) |
|
3120 |
|
3121 self.SizerDic["Sync1_InnerSizer"].AddMany([ |
|
3122 self.CheckBoxDic["Sync1Enable"], self.SizerDic["Sync1CycleTimeBox"], |
|
3123 self.SizerDic["Sync1ShiftTimeBox"] |
|
3124 ]) |
|
3125 |
|
3126 # sync1 box |
|
3127 self.SizerDic["Sync1Box"].Add(self.SizerDic["Sync1_InnerSizer"]) |
|
3128 |
|
3129 # sync0 shifttime box contents |
|
3130 self.SizerDic["Sync0_ShiftTimeSizer"].AddMany([ |
|
3131 self.StaticTextDic["Sync0ShiftTimeUserDefinedLabel"], |
|
3132 self.TextCtrlDic["Sync0ShiftTimeUserDefined_Ctl"] |
|
3133 ]) |
|
3134 |
|
3135 # sync0 shifttime box |
|
3136 self.SizerDic["Sync0ShiftTimeBox"].Add(self.SizerDic["Sync0_ShiftTimeSizer"]) |
|
3137 |
|
3138 # sync0 cycletime box contents |
|
3139 self.SizerDic["Sync0_CycleTimeSizer"].AddMany([ |
|
3140 self.RadioButtonDic["Sync0CycleTimeUnitRadioButton"], |
|
3141 self.ComboBoxDic["Sync0UnitCycleChoice"], |
|
3142 self.RadioButtonDic["Sync0CycleTimeUserDefinedRadioButton"], |
|
3143 self.TextCtrlDic["Sync0CycleTimeUserDefined_Ctl"] |
|
3144 ]) |
|
3145 |
|
3146 # sync0 cycletime box |
|
3147 self.SizerDic["Sync0CycleTimeBox"].Add(self.SizerDic["Sync0_CycleTimeSizer"]) |
|
3148 |
|
3149 self.SizerDic["Sync0_InnerSizer"].AddMany([ |
|
3150 self.CheckBoxDic["Sync0Enable"], self.SizerDic["Sync0CycleTimeBox"], |
|
3151 self.SizerDic["Sync0ShiftTimeBox"] |
|
3152 ]) |
|
3153 |
|
3154 # sync0 box |
|
3155 self.SizerDic["Sync0Box"].Add(self.SizerDic["Sync0_InnerSizer"]) |
|
3156 |
|
3157 # sync0, sync1 box |
|
3158 self.SizerDic["SyncMode_InnerSizer"].AddMany([ |
|
3159 self.SizerDic["Sync0Box"], self.SizerDic["Sync1Box"] |
|
3160 ]) |
|
3161 |
|
3162 # CyclicMode Box |
|
3163 self.SizerDic["CheckEnable_InnerSizer"].AddMany([ |
|
3164 self.StaticTextDic["SyncUnitCycleLabel"], |
|
3165 self.TextCtrlDic["SyncUnitCycle_Ctl"] |
|
3166 ]) |
|
3167 |
|
3168 self.SizerDic["OperationMode_InnerSizer"].AddMany([ |
|
3169 self.StaticTextDic["OperationModeLabel"], |
|
3170 self.ComboBoxDic["OperationModeChoice"], |
|
3171 self.CheckBoxDic["DCEnable"], self.SizerDic["CheckEnable_InnerSizer"] |
|
3172 ]) |
|
3173 |
|
3174 self.SizerDic["CyclicMode_InnerSizer"].AddMany([ |
|
3175 self.SizerDic["OperationMode_InnerSizer"], |
|
3176 self.SizerDic["SyncMode_InnerSizer"] |
|
3177 ]) |
|
3178 |
|
3179 self.SizerDic["CyclicModeBox"].Add(self.SizerDic["CyclicMode_InnerSizer"]) |
|
3180 |
|
3181 # Main Sizer |
|
3182 self.SizerDic["DCConfig_inner_main_sizer"].AddMany([ |
|
3183 self.StaticTextDic["MainLabel"], self.ApplyButton, |
|
3184 self.SizerDic["CyclicModeBox"] |
|
3185 ]) |
|
3186 |
|
3187 self.SizerDic["DCConfig_main_sizer"].Add(self.SizerDic["DCConfig_inner_main_sizer"]) |
|
3188 |
|
3189 self.SetSizer(self.SizerDic["DCConfig_main_sizer"]) |
|
3190 |
|
3191 self.Centre() |
|
3192 |
|
3193 self.UIOnOffSet(False) |
|
3194 self.LoadProjectDCData() |
|
3195 |
|
3196 def UIOnOffSet(self, activate): |
|
3197 if activate : |
|
3198 for object in self.RadioButtonDic: |
|
3199 self.RadioButtonDic[object].Enable() |
|
3200 |
|
3201 for object in self.ComboBoxDic: |
|
3202 if object == "OperationModeChoice": |
|
3203 continue |
|
3204 self.ComboBoxDic[object].Enable() |
|
3205 |
|
3206 for object in self.TextCtrlDic: |
|
3207 if object in ["SyncUnitCycle_Ctl", "InputReference_Ctl"]: |
|
3208 continue |
|
3209 self.TextCtrlDic[object].Enable() |
|
3210 |
|
3211 for object in self.CheckBoxDic: |
|
3212 if object == "DCEnable": |
|
3213 continue |
|
3214 self.CheckBoxDic[object].Enable() |
|
3215 |
|
3216 # initial set or DC enable uncheck |
|
3217 else : |
|
3218 for object in self.RadioButtonDic: |
|
3219 self.RadioButtonDic[object].Disable() |
|
3220 |
|
3221 for object in self.ComboBoxDic: |
|
3222 if object == "OperationModeChoice": |
|
3223 continue |
|
3224 self.ComboBoxDic[object].Disable() |
|
3225 |
|
3226 for object in self.TextCtrlDic: |
|
3227 if object == "SyncUnitCycle_Ctl": |
|
3228 continue |
|
3229 self.TextCtrlDic[object].Disable() |
|
3230 |
|
3231 for object in self.CheckBoxDic: |
|
3232 if object == "DCEnable": |
|
3233 continue |
|
3234 self.CheckBoxDic[object].Disable() |
|
3235 |
|
3236 for data in self.ESI_DC_Data: |
|
3237 index = self.Controler.ExtractHexDecValue(data["assign_activate"]) |
|
3238 if index == 0: |
|
3239 config_name = data["desc"] |
|
3240 self.ComboBoxDic["OperationModeChoice"].SetStringSelection(config_name) |
|
3241 |
|
3242 def CheckSync0Enable(self, evt): |
|
3243 if evt.GetInt(): |
|
3244 self.ComboBoxDic["Sync0UnitCycleChoice"].Enable() |
|
3245 self.RadioButtonDic["Sync0CycleTimeUnitRadioButton"].Enable() |
|
3246 self.RadioButtonDic["Sync0CycleTimeUserDefinedRadioButton"].Enable() |
|
3247 self.TextCtrlDic["Sync0CycleTimeUserDefined_Ctl"].Enable() |
|
3248 self.TextCtrlDic["Sync0ShiftTimeUserDefined_Ctl"].Enable() |
|
3249 else : |
|
3250 self.ComboBoxDic["Sync0UnitCycleChoice"].Disable() |
|
3251 self.RadioButtonDic["Sync0CycleTimeUnitRadioButton"].Disable() |
|
3252 self.RadioButtonDic["Sync0CycleTimeUserDefinedRadioButton"].Disable() |
|
3253 self.TextCtrlDic["Sync0CycleTimeUserDefined_Ctl"].Disable() |
|
3254 self.TextCtrlDic["Sync0ShiftTimeUserDefined_Ctl"].Disable() |
|
3255 self.RadioButtonDic["Sync0CycleTimeUnitRadioButton"].SetValue(False) |
|
3256 self.RadioButtonDic["Sync0CycleTimeUserDefinedRadioButton"].SetValue(False) |
|
3257 self.TextCtrlDic["Sync0CycleTimeUserDefined_Ctl"].SetValue("") |
|
3258 self.TextCtrlDic["Sync0ShiftTimeUserDefined_Ctl"].SetValue("") |
|
3259 |
|
3260 def CheckSync1Enable(self, evt): |
|
3261 if evt.GetInt(): |
|
3262 self.ComboBoxDic["Sync1UnitCycleChoice"].Enable() |
|
3263 self.RadioButtonDic["Sync1CycleTimeUnitRadioButton"].Enable() |
|
3264 self.RadioButtonDic["Sync1CycleTimeUserDefinedRadioButton"].Enable() |
|
3265 self.TextCtrlDic["Sync1CycleTimeUserDefined_Ctl"].Enable() |
|
3266 self.TextCtrlDic["Sync1ShiftTimeUserDefined_Ctl"].Enable() |
|
3267 else : |
|
3268 self.ComboBoxDic["Sync1UnitCycleChoice"].Disable() |
|
3269 self.RadioButtonDic["Sync1CycleTimeUnitRadioButton"].Disable() |
|
3270 self.RadioButtonDic["Sync1CycleTimeUserDefinedRadioButton"].Disable() |
|
3271 self.TextCtrlDic["Sync1CycleTimeUserDefined_Ctl"].Disable() |
|
3272 self.TextCtrlDic["Sync1ShiftTimeUserDefined_Ctl"].Disable() |
|
3273 self.RadioButtonDic["Sync1CycleTimeUnitRadioButton"].SetValue(False) |
|
3274 self.RadioButtonDic["Sync1CycleTimeUserDefinedRadioButton"].SetValue(False) |
|
3275 self.TextCtrlDic["Sync1CycleTimeUserDefined_Ctl"].SetValue("") |
|
3276 self.TextCtrlDic["Sync1ShiftTimeUserDefined_Ctl"].SetValue("") |
|
3277 |
|
3278 def CheckDCEnable(self, evt): |
|
3279 ns_mode = 1 |
|
3280 task_cycle_ns = self.GetInterval(ns_mode) |
|
3281 sync0_cycle_factor = None |
|
3282 sync1_cycle_factor = None |
|
3283 |
|
3284 #task_cycle_ns = self.Controler.GetCTRoot()._Ticktime |
|
3285 if (task_cycle_ns > 0): |
|
3286 self.UIOnOffSet(evt.GetInt()) |
|
3287 |
|
3288 if evt.GetInt(): |
|
3289 # default select DC enable sync0 |
|
3290 default_list_num = 0 |
|
3291 config_name = self.ESI_DC_Data[default_list_num]["desc"] |
|
3292 assign_act = self.ESI_DC_Data[default_list_num]["assign_activate"] |
|
3293 sync0_cycle_time_ns = self.ESI_DC_Data[default_list_num]["cycletime_sync0"] |
|
3294 if sync0_cycle_time_ns == 0 : |
|
3295 sync0_cycle_factor = self.ESI_DC_Data[default_list_num]["cycletime_sync0_factor"] |
|
3296 sync0_shift_time_ns = self.ESI_DC_Data[default_list_num]["shifttime_sync0"] |
|
3297 sync1_cycle_time_ns = self.ESI_DC_Data[default_list_num]["cycletime_sync1"] |
|
3298 if sync1_cycle_time_ns == 0 : |
|
3299 sync1_cycle_factor = self.ESI_DC_Data[default_list_num]["cycletime_sync1_factor"] |
|
3300 sync1_shift_time_ns = self.ESI_DC_Data[default_list_num]["shifttime_sync1"] |
|
3301 |
|
3302 cal_assign_act = self.Controler.ExtractHexDecValue(assign_act) |
|
3303 sync0_cycle_time_us = str(int(sync0_cycle_time_ns) / 1000) |
|
3304 sync0_shift_time_us = str(int(sync0_shift_time_ns) / 1000) |
|
3305 sync1_cycle_time_us = str(int(sync1_cycle_time_ns) / 1000) |
|
3306 sync1_shift_time_us = str(int(sync1_shift_time_ns) / 1000) |
|
3307 |
|
3308 task_cycle_to_us = str(int(task_cycle_ns) / 1000) |
|
3309 |
|
3310 # DC sync0 mode |
|
3311 if cal_assign_act == 768: |
|
3312 # Disable About Sync1 Objects |
|
3313 self.CheckBoxDic["Sync1Enable"].SetValue(False) |
|
3314 self.RadioButtonDic["Sync1CycleTimeUnitRadioButton"].Disable() |
|
3315 self.ComboBoxDic["Sync1UnitCycleChoice"].Disable() |
|
3316 self.RadioButtonDic["Sync1CycleTimeUserDefinedRadioButton"].Disable() |
|
3317 self.TextCtrlDic["Sync1CycleTimeUserDefined_Ctl"].Disable() |
|
3318 self.TextCtrlDic["Sync1ShiftTimeUserDefined_Ctl"].Disable() |
|
3319 |
|
3320 else : |
|
3321 self.CheckBoxDic["Sync1Enable"].SetValue(True) |
|
3322 if sync1_cycle_factor is not None: |
|
3323 self.RadioButtonDic["Sync1CycleTimeUnitRadioButton"].SetValue(True) |
|
3324 self.RadioButtonDic["Sync1CycleTimeUserDefinedRadioButton"].SetValue(False) |
|
3325 self.TextCtrlDic["Sync1CycleTimeUserDefined_Ctl"].Disable() |
|
3326 self.SetSyncUnitCycle(sync1_cycle_factor, |
|
3327 self.ComboBoxDic["Sync1UnitCycleChoice"]) |
|
3328 else : |
|
3329 self.RadioButtonDic["Sync1CycleTimeUnitRadioButton"].SetValue(False) |
|
3330 self.RadioButtonDic["Sync1CycleTimeUserDefinedRadioButton"].SetValue(True) |
|
3331 self.ComboBoxDic["Sync1UnitCycleChoice"].Disable() |
|
3332 self.TextCtrlDic["Sync1CycleTimeUserDefined_Ctl"].SetValue(sync1_cycle_time_us) |
|
3333 |
|
3334 self.TextCtrlDic["Sync1ShiftTimeUserDefined_Ctl"].SetValue(sync1_shift_time_us) |
|
3335 |
|
3336 # Set Sync0 Objects |
|
3337 self.CheckBoxDic["Sync0Enable"].SetValue(True) |
|
3338 if sync0_cycle_factor is not None: |
|
3339 self.RadioButtonDic["Sync0CycleTimeUnitRadioButton"].SetValue(True) |
|
3340 self.RadioButtonDic["Sync0CycleTimeUserDefinedRadioButton"].SetValue(False) |
|
3341 self.TextCtrlDic["Sync0CycleTimeUserDefined_Ctl"].Disable() |
|
3342 self.SetSyncUnitCycle(sync0_cycle_factor, |
|
3343 self.ComboBoxDic["Sync0UnitCycleChoice"]) |
|
3344 else : |
|
3345 self.RadioButtonDic["Sync0CycleTimeUnitRadioButton"].SetValue(False) |
|
3346 self.RadioButtonDic["Sync0CycleTimeUserDefinedRadioButton"].SetValue(True) |
|
3347 self.ComboBoxDic["Sync0UnitCycleChoice"].Disable() |
|
3348 self.TextCtrlDic["Sync0CycleTimeUserDefined_Ctl"].SetValue(sync0_cycle_time_us) |
|
3349 |
|
3350 self.TextCtrlDic["Sync0ShiftTimeUserDefined_Ctl"].SetValue(sync0_shift_time_us) |
|
3351 |
|
3352 self.ComboBoxDic["OperationModeChoice"].SetStringSelection(config_name) |
|
3353 self.TextCtrlDic["SyncUnitCycle_Ctl"].SetValue(task_cycle_to_us) |
|
3354 else : |
|
3355 self.CheckBoxDic["Sync0Enable"].SetValue(False) |
|
3356 self.CheckBoxDic["Sync1Enable"].SetValue(False) |
|
3357 self.RadioButtonDic["Sync0CycleTimeUnitRadioButton"].SetValue(False) |
|
3358 self.RadioButtonDic["Sync0CycleTimeUserDefinedRadioButton"].SetValue(False) |
|
3359 self.RadioButtonDic["Sync1CycleTimeUnitRadioButton"].SetValue(False) |
|
3360 self.RadioButtonDic["Sync1CycleTimeUserDefinedRadioButton"].SetValue(False) |
|
3361 self.TextCtrlDic["Sync0CycleTimeUserDefined_Ctl"].SetValue("") |
|
3362 self.TextCtrlDic["Sync0ShiftTimeUserDefined_Ctl"].SetValue("") |
|
3363 self.TextCtrlDic["Sync1CycleTimeUserDefined_Ctl"].SetValue("") |
|
3364 self.TextCtrlDic["Sync1ShiftTimeUserDefined_Ctl"].SetValue("") |
|
3365 |
|
3366 else : |
|
3367 self.UIOnOffSet(False) |
|
3368 #error_str = "DC Enable is not possble, please set task interval" |
|
3369 error_str = "Can't Set DC Enable" |
|
3370 self.Controler.CommonMethod.CreateErrorDialog(error_str) |
|
3371 |
|
3372 def SetSyncUnitCycle(self, factor, object): |
|
3373 # factor > 0 ==> * factor, factor < 0 ==> / factor |
|
3374 factor_to_int = int(factor) |
|
3375 if factor_to_int > 0: |
|
3376 lists = object.GetStrings() |
|
3377 |
|
3378 for token in lists: |
|
3379 temp = token.split(" ") |
|
3380 if (temp[0] == "x") and (int(temp[1]) == factor_to_int): |
|
3381 object.SetStringSelection(token) |
|
3382 return True |
|
3383 |
|
3384 else : |
|
3385 lists = object.GetStrings() |
|
3386 |
|
3387 for token in lists: |
|
3388 temp = token.split(" ") |
|
3389 if (temp[0] == "/") and (int(temp[1]) == factor_to_int): |
|
3390 object.SetStringSelection(token) |
|
3391 return True |
|
3392 |
|
3393 return False |
|
3394 |
|
3395 def GetInterval(self, mode): |
|
3396 project_infos = self.Controler.GetCTRoot().GetProjectInfos() |
|
3397 for project_info_list in project_infos["values"]: |
|
3398 if project_info_list["name"] == "Resources" : |
|
3399 token = project_info_list["values"][0]["tagname"] |
|
3400 |
|
3401 tasks, instances = self.Controler.GetCTRoot().GetEditedResourceInfos(token) |
|
3402 try: |
|
3403 task_cycle_ns = self.ParseTime(tasks[0]["Interval"]) |
|
3404 except : |
|
3405 task_cycle_ns = 0 |
|
3406 task_cycle_us = int(task_cycle_ns) / 1000 |
|
3407 |
|
3408 # mode == 1 ==> return ns |
|
3409 # mode == 2 ==> return us |
|
3410 |
|
3411 if mode == 1: |
|
3412 return task_cycle_ns |
|
3413 if mode == 2: |
|
3414 return str(task_cycle_us) |
|
3415 |
|
3416 def ParseTime(self, input): |
|
3417 # input example : 't#1ms' |
|
3418 # temp.split('#') -> ['t', '1ms'] |
|
3419 temp = input.split('#') |
|
3420 |
|
3421 # temp[1] : '1ms' |
|
3422 # temp[-2:] : 'ms' |
|
3423 # temp[:-2] : '1' |
|
3424 if temp[1][-2:] == "ms": |
|
3425 # convert nanosecond unit |
|
3426 result = int(temp[1][:-2]) * 1000000 |
|
3427 elif temp[1][-2:] == "us": |
|
3428 result = int(temp[1][:-2]) * 1000 |
|
3429 |
|
3430 return str(result) |
|
3431 |
|
3432 def SelectSync0CycleTime(self, evt): |
|
3433 selected_object = evt.GetEventObject() |
|
3434 |
|
3435 if selected_object.GetLabel() == "User Defined" : |
|
3436 self.RadioButtonDic["Sync0CycleTimeUnitRadioButton"].SetValue(False) |
|
3437 self.TextCtrlDic["Sync0CycleTimeUserDefined_Ctl"].Enable() |
|
3438 self.ComboBoxDic["Sync0UnitCycleChoice"].Disable() |
|
3439 elif selected_object.GetLabel() == "Sync Unit Cycle" : |
|
3440 self.RadioButtonDic["Sync0CycleTimeUserDefinedRadioButton"].SetValue(False) |
|
3441 self.ComboBoxDic["Sync0UnitCycleChoice"].Enable() |
|
3442 self.TextCtrlDic["Sync0CycleTimeUserDefined_Ctl"].Disable() |
|
3443 |
|
3444 def SelectSync1CycleTime(self, evt): |
|
3445 selected_object = evt.GetEventObject() |
|
3446 |
|
3447 if selected_object.GetLabel() == "User Defined" : |
|
3448 self.RadioButtonDic["Sync1CycleTimeUnitRadioButton"].SetValue(False) |
|
3449 self.TextCtrlDic["Sync1CycleTimeUserDefined_Ctl"].Enable() |
|
3450 self.ComboBoxDic["Sync1UnitCycleChoice"].Disable() |
|
3451 elif selected_object.GetLabel() == "Sync Unit Cycle" : |
|
3452 self.RadioButtonDic["Sync1CycleTimeUserDefinedRadioButton"].SetValue(False) |
|
3453 self.ComboBoxDic["Sync1UnitCycleChoice"].Enable() |
|
3454 self.TextCtrlDic["Sync1CycleTimeUserDefined_Ctl"].Disable() |
|
3455 |
|
3456 def GetCycle(self, period, section): |
|
3457 temp = section.split(" ") |
|
3458 |
|
3459 if temp[0] == "x": |
|
3460 result = int(period) * int(temp[1]) |
|
3461 elif temp[0] == "/" : |
|
3462 result = int(period) / int(temp[1]) |
|
3463 else : |
|
3464 result = "" |
|
3465 |
|
3466 return result |
|
3467 |
|
3468 def OnClickApplyButton(self, evt): |
|
3469 us_mode = 2 |
|
3470 dc_enable = self.CheckBoxDic["DCEnable"].GetValue() |
|
3471 dc_desc = self.ComboBoxDic["OperationModeChoice"].GetStringSelection() |
|
3472 dc_assign_activate = self.ESI_DC_Data[0]["assign_activate"] |
|
3473 dc_assign_activate_mod = dc_assign_activate.split('x')[1] |
|
3474 |
|
3475 if self.RadioButtonDic["Sync0CycleTimeUnitRadioButton"].GetValue(): |
|
3476 temp = self.ComboBoxDic["Sync0UnitCycleChoice"].GetStringSelection() |
|
3477 dc_sync0_cycle = "1_" + str(self.GetCycle(self.GetInterval(us_mode), temp)) |
|
3478 elif self.RadioButtonDic["Sync0CycleTimeUserDefinedRadioButton"].GetValue(): |
|
3479 dc_sync0_cycle = "2_" + self.TextCtrlDic["Sync0CycleTimeUserDefined_Ctl"].GetValue() |
|
3480 else : |
|
3481 dc_sync0_cycle = "" |
|
3482 |
|
3483 if self.RadioButtonDic["Sync1CycleTimeUnitRadioButton"].GetValue(): |
|
3484 temp = self.ComboBoxDic["Sync1UnitCycleChoice"].GetStringSelection() |
|
3485 dc_sync1_cycle = "1_" + self.GetCycle(self.GetInterval(us_mode), temp) |
|
3486 elif self.RadioButtonDic["Sync1CycleTimeUserDefinedRadioButton"].GetValue(): |
|
3487 dc_sync1_cycle = "2_" + self.TextCtrlDic["Sync1CycleTimeUserDefined_Ctl"].GetValue() |
|
3488 else : |
|
3489 dc_sync1_cycle = "" |
|
3490 |
|
3491 dc_sync0_shift = self.TextCtrlDic["Sync0ShiftTimeUserDefined_Ctl"].GetValue() |
|
3492 dc_sync1_shift = self.TextCtrlDic["Sync1ShiftTimeUserDefined_Ctl"].GetValue() |
|
3493 |
|
3494 self.Controler.BaseParams.setDC_Enable(dc_enable) |
|
3495 self.Controler.BaseParams.setDC_Desc(dc_desc) |
|
3496 self.Controler.BaseParams.setDC_Assign_Activate(dc_assign_activate_mod) |
|
3497 if dc_sync0_cycle: |
|
3498 self.Controler.BaseParams.setDC_Sync0_Cycle_Time(dc_sync0_cycle) |
|
3499 if dc_sync0_shift: |
|
3500 self.Controler.BaseParams.setDC_Sync0_Shift_Time(dc_sync0_shift) |
|
3501 if dc_sync1_cycle: |
|
3502 self.Controler.BaseParams.setDC_Sync1_Cycle_Time(dc_sync1_cycle) |
|
3503 if dc_sync1_shift: |
|
3504 self.Controler.BaseParams.setDC_Sync1_Shift_Time(dc_sync1_shift) |
|
3505 project_infos = self.Controler.GetCTRoot().CTNRequestSave() |
|
3506 |
|
3507 def GetSymbol(self, period, cycle): |
|
3508 cmp1 = int(period) |
|
3509 cmp2 = int(cycle) |
|
3510 |
|
3511 if cmp1 == cmp2 : |
|
3512 return "x 1" |
|
3513 elif cmp2 > cmp1 : |
|
3514 temp = cmp2 / cmp1 |
|
3515 result = "x " + str(temp) |
|
3516 else : |
|
3517 temp = cmp1 / cmp2 |
|
3518 result = "/ " + str(temp) |
|
3519 |
|
3520 return result |
|
3521 |
|
3522 def SetSyncCycle(self, period, sync0_cycle, sync1_cycle): |
|
3523 if sync0_cycle != "None": |
|
3524 self.CheckBoxDic["Sync0Enable"].SetValue(True) |
|
3525 temp = sync0_cycle.split("_") |
|
3526 if temp[0] == "1": |
|
3527 symbol = self.GetSymbol(period, temp[1]) |
|
3528 self.ComboBoxDic["Sync0UnitCycleChoice"].SetStringSelection(symbol) |
|
3529 self.TextCtrlDic["Sync0CycleTimeUserDefined_Ctl"].Disable() |
|
3530 self.RadioButtonDic["Sync0CycleTimeUnitRadioButton"].SetValue(True) |
|
3531 else : |
|
3532 self.TextCtrlDic["Sync0CycleTimeUserDefined_Ctl"].SetValue(temp[1]) |
|
3533 self.ComboBoxDic["Sync0UnitCycleChoice"].Disable() |
|
3534 self.RadioButtonDic["Sync0CycleTimeUserDefinedRadioButton"].SetValue(True) |
|
3535 |
|
3536 if sync1_cycle != "None": |
|
3537 self.CheckBoxDic["Sync1Enable"].SetValue(True) |
|
3538 temp = sync1_cycle.split("_") |
|
3539 if temp[0] == "1": |
|
3540 symbol = self.GetSymbol(period, temp[1]) |
|
3541 self.ComboBoxDic["Sync1UnitChoice"].SetStringSelection(symbol) |
|
3542 self.TextCtrlDic["Sync1CycleTimeUserDefined_Ctl"].Disable() |
|
3543 self.RadioButtonDic["Sync1CycleTimeUnitRadioButton"].SetValue(True) |
|
3544 else : |
|
3545 self.TextCtrlDic["Sync1CycleTimeUserDefined_Ctl"].SetValue(temp[1]) |
|
3546 self.ComboBoxDic["Sync1UnitChoice"].Disable() |
|
3547 self.RadioButtonDic["Sync1CycleTimeUserDefinedRadioButton"].SetValue(True) |
|
3548 |
|
3549 def LoadProjectDCData(self): |
|
3550 ns_mode = 1 |
|
3551 task_cycle_ns = self.GetInterval(ns_mode) |
|
3552 task_cycle_to_us = int(task_cycle_ns) / 1000 |
|
3553 dc_enable = self.Controler.BaseParams.getDC_Enable() |
|
3554 dc_desc = self.Controler.BaseParams.getDC_Desc() |
|
3555 dc_assign_activate = self.Controler.BaseParams.getDC_Assign_Activate() |
|
3556 dc_sync0_cycle = self.Controler.BaseParams.getDC_Sync0_Cycle_Time() |
|
3557 dc_sync0_shift = self.Controler.BaseParams.getDC_Sync0_Shift_Time() |
|
3558 dc_sync1_cycle = self.Controler.BaseParams.getDC_Sync1_Cycle_Time() |
|
3559 dc_sync1_shift = self.Controler.BaseParams.getDC_Sync1_Shift_Time() |
|
3560 |
|
3561 self.UIOnOffSet(dc_enable) |
|
3562 |
|
3563 if dc_enable: |
|
3564 self.CheckBoxDic["DCEnable"].SetValue(dc_enable) |
|
3565 self.ComboBoxDic["OperationModeChoice"].SetStringSelection(dc_desc) |
|
3566 self.TextCtrlDic["SyncUnitCycle_Ctl"].SetValue(str(task_cycle_to_us)) |
|
3567 self.SetSyncCycle(str(task_cycle_to_us), dc_sync0_cycle, dc_sync1_cycle) |
|
3568 if dc_sync0_shift != "None": |
|
3569 self.TextCtrlDic["Sync0ShiftTimeUserDefined_Ctl"].SetValue(dc_sync0_shift) |
|
3570 if dc_sync1_shift != "None": |
|
3571 self.TextCtrlDic["Sync1ShiftTimeUserDefined_Ctl"].SetValue(dc_sync1_shift) |
|
3572 |
|
3573 if dc_assign_activate == "300": |
|
3574 self.CheckBoxDic["Sync1Enable"].SetValue(False) |
|
3575 self.RadioButtonDic["Sync1CycleTimeUnitRadioButton"].Disable() |
|
3576 self.ComboBoxDic["Sync1UnitCycleChoice"].Disable() |
|
3577 self.RadioButtonDic["Sync1CycleTimeUserDefinedRadioButton"].Disable() |
|
3578 self.TextCtrlDic["Sync1CycleTimeUserDefined_Ctl"].Disable() |
|
3579 self.TextCtrlDic["Sync1ShiftTimeUserDefined_Ctl"].Disable() |
|
3580 |
|
3581 |
|
3582 |
|
3583 |
|
3584 |
|
3585 |
|
3586 |
|
3587 |
|
3588 |
|
3589 |