ssweber (Customer) asked a question.

Import/Export and Version Control for Click Ladder Logic

I use Click PLCs and got tired of not being able to diff two versions of a program, or build I/O mappings without clicking through dialogs one at a time. I've added Ladder import/export to ClickNick (some of you might remember it, the nickname autocomplete overlay for the Click editor).

 

Excel to Click Build your I/O mapping in a spreadsheet and paste it straight into Click.

 

CreateInExcelLoadCsvPasteInClick.gifCSV export and diff Export your entire ladder program to CSV. Diff two versions, keep it in git, or just read through logic in a spreadsheet.imageSimulation and testing ClickNick can also convert a Click project into pyrung, a Python library that simulates Click's scan cycle. Then it's even easier to read through, as your Address will have the nicknames. You can write tests with pytest and step through with breakpoints, like "does the machine alarm when it hits this condition" or "why did the motor keep running." When you're done, convert back and paste into Click.

  1. from pyrung import Bool, PLC, Program, Rung, out
  2.  
  3. Button = Bool("Button")
  4. Light = Bool("Light")
  5.  
  6. with Program() as logic:
  7. with Rung(Button):
  8. out(Light)
  9.  
  10. with PLC(logic) as plc:
  11. Button.value = True
  12. plc.step()
  13. assert Light.value is True

Each piece works on its own, use what helps.

 

To install ClickNick.

 

1) You'll need `uv`, a Python package installer:

 

run this in cmd:

  1. powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

then after:

 

uv tool install clicknick

  1. uv tool install clicknick

You also will want Microsoft Access ODBC drivers (if they arn't already installed on your computer: https://github.com/ssweber/clicknick/issues/17).

 

Issues and feedback welcome on GitHub.


  • ssweber (Customer)

    I've worked through all the bugs I could find on my programs, but I'm sure we'll still find a few hiding.I haven't mapped the Email, Home, Velocity, Position instructions to simple function names in the csv yet, so those will come through as raw tables, but the round-trip will still paste-back in (if that makes any sense).

     

    Here's ADC's https://support.automationdirect.com/examples.html EP-MISC-001 daylight's saving time, 'C2 Clicks' subroutine converted to csv, and pyrung:

     

    1. marker,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,AA,AB,AC,AD,AE,AF
    2. #,SD23 (Day of the Week)
    3. #,Sunday = 1
    4. #,
    5. #,"At 2:00am, the second Sunday of the month of March, Set SC121 to advance the clock 1 hour. ""Spring forward"". "
    6. #,
    7. R,SD24==2,SD23==1,SD21==3,SD22>=8,SD22<15,~SC121,T,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,latch(SC121)
    8. ,,,,,,,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,out(C2)
    9. #,"At 2:00am, the first Sunday of the month of November, Reset SC121 to move the clock 1 hour back. ""Fall back"""
    10. #,
    11. R,SD24==2,SD23==1,SD21==11,SD22<=7,SC121,T,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,reset(SC121)
    12. ,,,,,,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,out(C3)
    13. #,"If your PLC has network access to a time server, then you can use SC120 to update the PLC clock."
    14. #,
    15. #,"See help topic CL272 in the software help file for more information about the ""Network Timer Service"" function."
    16. #,
    17. R,C2,T,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,out(SC120)
    18. ,C3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
    19. R,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,return()
    1. # Generated by pyrung from Click ladder CSV
    2.  
    3. from pyrung import Rung, subroutine, Or, latch, out, reset, comment
    4. from pyrung.core.system_points import system
    5. from tags import Fall_Time_Change, Spring_Time_Change, _Network_Time_DST, _Network_Time_Request
    6.  
    7.  
    8. @subroutine("C2 Clicks", strict=False)
    9. def c2_clicks():
    10. comment("""\
    11. SD23 (Day of the Week)
    12. Sunday = 1
    13.  
    14. At 2:00am, the second Sunday of the month of March, Set SC121 to advance the clock 1 hour. "Spring forward". """)
    15. with Rung(system.rtc.hour == 2, system.rtc.weekday == 1, system.rtc.month == 3, system.rtc.day >= 8, system.rtc.day < 15, ~_Network_Time_DST):
    16. latch(_Network_Time_DST)
    17. out(Spring_Time_Change)
    18.  
    19. comment("At 2:00am, the first Sunday of the month of November, Reset SC121 to move the clock 1 hour back. \"Fall back\"")
    20. with Rung(system.rtc.hour == 2, system.rtc.weekday == 1, system.rtc.month == 11, system.rtc.day <= 7, _Network_Time_DST):
    21. reset(_Network_Time_DST)
    22. out(Fall_Time_Change)
    23.  
    24. comment("""\
    25. If your PLC has network access to a time server, then you can use SC120 to update the PLC clock.
    26.  
    27. See help topic CL272 in the software help file for more information about the "Network Timer Service" function.""")
    28. with Rung(Or(Spring_Time_Change, Fall_Time_Change)):
    29. out(_Network_Time_Request)
    30.  

     

    Expand Post