Command-line Usage¶
Using pytmc¶
Once pytmc has been installed in a virtual environment the pytmc
command
can be called from the command line to generate .db files and more.
pytmc db¶
“pytmc-db” is a command line utility for generating epics records files from TwinCAT3 .tmc files. This program is designed to work in conjunction with ESS’s m-epics-twincat-ads driver.
usage: pytmc db [-h] [--dbd DBD] [--allow-errors] [--no-error-context]
[--plc PLC] [--archive-file ARCHIVE_FILE | --no-archive-file]
INPUT [OUTPUT]
Positional Arguments¶
- INPUT
Path to interpreted .tmc file, or a .tsproj project
- OUTPUT
Path to output .db file
Default: <_io.TextIOWrapper name=’<stdout>’ mode=’w’ encoding=’UTF-8’>
Named Arguments¶
- --dbd, -d
Specify an expanded .dbd file for validating fields (requires pyPDB)
- --allow-errors, -i
Generate the .db file even if linter issues are found
Default: False
- --no-error-context
Do not show db file context around errors
Default: False
- --plc
The PLC name, if specifying a .tsproj file
- --archive-file
Save an archive configuration file. Defaults to OUTPUT.archive if specified
- --no-archive-file
Do not write the archive file, regardless of OUTPUT filename settings.
Default: False
pytmc stcmd¶
“pytmc-stcmd” is a command line utility for generating ESS/ethercatmc-capable EPICS startup st.cmd files directly from TwinCAT3 .tsproj projects.
Relies on the existence (and linking) of FB_MotionStage function blocks.
usage: pytmc stcmd [-h] [--plc PLC_NAME] [-p PREFIX] [--hashbang HASHBANG]
[--binary BINARY_NAME] [-n NAME] [--only-motor]
[--db-path DB_PATH] [--dbd DBD] [--delim DELIM] [--debug]
[--template TEMPLATE_FILENAME]
[--template-path TEMPLATE_PATH] [--allow-errors]
tsproj_project
Positional Arguments¶
- tsproj_project
Path to .tsproj project
Named Arguments¶
- --plc
PLC project name, if multiple exist
- -p, --prefix
PV prefix for the IOC
- --hashbang
Indicates to the shell which binary to use for the st.cmd script
Default: “../../bin/rhel7-x86_64/adsIoc”
- --binary
IOC application binary name
Default: “adsIoc”
- -n, --name
IOC name (defaults to project name)
- --only-motor
Parse the project only for motor records, skipping other variables with pytmc pragmas
Default: False
- --db-path
Path for db files
Default: “.”
- --dbd
Path to the IOC dbd file
- --delim
Preferred PV delimiter
Default: “:”
- --debug, -d
Post-stcmd, open an interactive Python session
Default: False
- --template
st.cmd Jinja2 template
Default: “stcmd_default.cmd”
- --template-path
Location where templates are stored
Default: “.”
- --allow-errors
Allow non-fatal errors to be ignored
Default: False
pytmc xmltranslate¶
Tool for making XML-formatted files human-readable
Output uses the following rules: For a line of xml that appears as the following: <tag attr=qual…> text </tag> tail
Note that tail takes precedence over text.
This program will output the following: {attrs:qual…} tag text tail
Tags contained by other tags are indented and printed on the following line.
This tool was created for exploring .tpy files but is well suited to reading any xml formatted file.
usage: pytmc xmltranslate [-h] [-d DEPTH] [-i INDENT_SIZE] input_file
Positional Arguments¶
- input_file
input file
Named Arguments¶
- -d, --depth
Recursive limit for exploring the file
Default: 7
- -i, --indent_size
Indent size for output formatting
Default: 4
pytmc debug¶
“pytmc-debug” is a Qt interface that shows information about how pytmc interprets TwinCAT3 .tmc files.
usage: pytmc debug [-h] [-d DBD] INPUT
Positional Arguments¶
- INPUT
Path to .tmc file
Named Arguments¶
- -d, --dbd
Specify an expanded .dbd file for validating fields (requires pyPDB)
pytmc pragmalint¶
“pytmc pragmalint” is a command line utility for linting PyTMC pragmas in a given TwinCAT project or source code file
usage: pytmc pragmalint [-h] [--markdown] [--verbose] filename
Positional Arguments¶
- filename
Path to .tsproj project or source code file
Named Arguments¶
- --markdown
Make output more markdown-friendly, for easier sharing
Default: False
- --verbose, -v
Show all pragmas, including good ones
Default: False
pytmc stcmd¶
“pytmc-stcmd” is a command line utility for generating ESS/ethercatmc-capable EPICS startup st.cmd files directly from TwinCAT3 .tsproj projects.
Relies on the existence (and linking) of FB_MotionStage function blocks.
usage: pytmc stcmd [-h] [--plc PLC_NAME] [-p PREFIX] [--hashbang HASHBANG]
[--binary BINARY_NAME] [-n NAME] [--only-motor]
[--db-path DB_PATH] [--dbd DBD] [--delim DELIM] [--debug]
[--template TEMPLATE_FILENAME]
[--template-path TEMPLATE_PATH] [--allow-errors]
tsproj_project
Positional Arguments¶
- tsproj_project
Path to .tsproj project
Named Arguments¶
- --plc
PLC project name, if multiple exist
- -p, --prefix
PV prefix for the IOC
- --hashbang
Indicates to the shell which binary to use for the st.cmd script
Default: “../../bin/rhel7-x86_64/adsIoc”
- --binary
IOC application binary name
Default: “adsIoc”
- -n, --name
IOC name (defaults to project name)
- --only-motor
Parse the project only for motor records, skipping other variables with pytmc pragmas
Default: False
- --db-path
Path for db files
Default: “.”
- --dbd
Path to the IOC dbd file
- --delim
Preferred PV delimiter
Default: “:”
- --debug, -d
Post-stcmd, open an interactive Python session
Default: False
- --template
st.cmd Jinja2 template
Default: “stcmd_default.cmd”
- --template-path
Location where templates are stored
Default: “.”
- --allow-errors
Allow non-fatal errors to be ignored
Default: False
pytmc summary¶
“pytmc-summary” is a command line utility for inspecting TwinCAT3 .tsproj projects.
usage: pytmc summary [-h] [--all] [--outline] [--boxes] [--code] [--plcs]
[--nc] [--symbols] [--types]
[--filter-types FILTER_TYPES] [--links] [--markdown]
[--debug]
filename
Positional Arguments¶
- filename
Path to project or solution (.tsproj, .sln)
Named Arguments¶
- --all, -a
All possible information
Default: False
- --outline
Outline XML
Default: False
- --boxes, -b
Show boxes
Default: False
- --code, -c
Show code
Default: False
- --plcs, -p
Show plcs
Default: False
- --nc, -n
Show NC axes
Default: False
- --symbols, -s
Show symbols
Default: False
- --types
Show TMC types and record suffixes, if available
Default: False
- --filter-types
Filter the types shown by name
- --links, -l
Show links
Default: False
- --markdown
Make output more markdown-friendly, for easier sharing
Default: False
- --debug, -d
Post-summary, open an interactive Python session
Default: False
Templates¶
stcmd_default.cmd¶
#!{{hashbang}}
< envPaths
epicsEnvSet("IOCNAME", "{{name}}" )
epicsEnvSet("ENGINEER", "{{user}}" )
epicsEnvSet("LOCATION", "{{prefix}}" )
epicsEnvSet("IOCSH_PS1", "$(IOCNAME)> " )
cd "$(TOP)"
# Run common startup commands for linux soft IOC's
< /reg/d/iocCommon/All/pre_linux.cmd
# Register all support components
dbLoadDatabase("dbd/{{binary_name}}.dbd")
{{binary_name}}_registerRecordDeviceDriver(pdbbase)
cd "$(TOP)/db"
epicsEnvSet("ASYN_PORT", "{{asyn_port}}")
epicsEnvSet("IPADDR", "{{plc_ip}}")
epicsEnvSet("AMSID", "{{plc_ams_id}}")
epicsEnvSet("IPPORT", "{{plc_ads_port}}")
adsAsynPortDriverConfigure("$(ASYN_PORT)","$(IPADDR)","$(AMSID)","$(IPPORT)", 1000, 0, 0, 50, 100, 1000, 0)
{% if motors %}
epicsEnvSet("MOTOR_PORT", "{{motor_port}}")
epicsEnvSet("PREFIX", "{{prefix}}{{delim}}")
epicsEnvSet("ECM_NUMAXES", "{{motors|length}}")
epicsEnvSet("NUMAXES", "{{motors|length}}")
EthercatMCCreateController("$(MOTOR_PORT)", "$(ASYN_PORT)", "$(NUMAXES)", "200", "1000")
#define ASYN_TRACE_ERROR 0x0001
#define ASYN_TRACEIO_DEVICE 0x0002
#define ASYN_TRACEIO_FILTER 0x0004
#define ASYN_TRACEIO_DRIVER 0x0008
#define ASYN_TRACE_FLOW 0x0010
#define ASYN_TRACE_WARNING 0x0020
#define ASYN_TRACE_INFO 0x0040
asynSetTraceMask("$(ASYN_PORT)", -1, 0x41)
#define ASYN_TRACEIO_NODATA 0x0000
#define ASYN_TRACEIO_ASCII 0x0001
#define ASYN_TRACEIO_ESCAPE 0x0002
#define ASYN_TRACEIO_HEX 0x0004
asynSetTraceIOMask("$(ASYN_PORT)", -1, 2)
#define ASYN_TRACEINFO_TIME 0x0001
#define ASYN_TRACEINFO_PORT 0x0002
#define ASYN_TRACEINFO_SOURCE 0x0004
#define ASYN_TRACEINFO_THREAD 0x0008
asynSetTraceInfoMask("$(ASYN_PORT)", -1, 5)
#define AMPLIFIER_ON_FLAG_CREATE_AXIS 1
#define AMPLIFIER_ON_FLAG_WHEN_HOMING 2
#define AMPLIFIER_ON_FLAG_USING_CNEN 4
{% for motor in motors | sort(attribute='nc_axis.axis_number') %}
epicsEnvSet("AXIS_NO", "{{motor.nc_axis.axis_number}}")
epicsEnvSet("MOTOR_PREFIX", "{{motor|epics_prefix}}")
epicsEnvSet("MOTOR_NAME", "{{motor|epics_suffix}}")
epicsEnvSet("DESC", "{{motor.name}} / {{motor.nc_axis.name}}")
epicsEnvSet("EGU", "{{motor.nc_axis.units}}")
epicsEnvSet("PREC", "{{motor|pragma('precision', 3) }}")
epicsEnvSet("AXISCONFIG", "{{motor|pragma('axisconfig', '')}}")
epicsEnvSet("ECAXISFIELDINIT", "{{motor|pragma('additional_fields', '') }}")
epicsEnvSet("AMPLIFIER_FLAGS", "{{motor|pragma('amplifier_flags', '') }}")
EthercatMCCreateAxis("$(MOTOR_PORT)", "$(AXIS_NO)", "$(AMPLIFIER_FLAGS)", "$(AXISCONFIG)")
dbLoadRecords("EthercatMC.template", "PREFIX=$(MOTOR_PREFIX), MOTOR_NAME=$(MOTOR_NAME), R=$(MOTOR_NAME)-, MOTOR_PORT=$(MOTOR_PORT), ASYN_PORT=$(ASYN_PORT), AXIS_NO=$(AXIS_NO), DESC=$(DESC), PREC=$(PREC) $(ECAXISFIELDINIT)")
dbLoadRecords("EthercatMCreadback.template", "PREFIX=$(MOTOR_PREFIX), MOTOR_NAME=$(MOTOR_NAME), R=$(MOTOR_NAME)-, MOTOR_PORT=$(MOTOR_PORT), ASYN_PORT=$(ASYN_PORT), AXIS_NO=$(AXIS_NO), DESC=$(DESC), PREC=$(PREC) ")
dbLoadRecords("EthercatMCdebug.template", "PREFIX=$(MOTOR_PREFIX), MOTOR_NAME=$(MOTOR_NAME), MOTOR_PORT=$(MOTOR_PORT), AXIS_NO=$(AXIS_NO), PREC=3")
{% endfor %}
{% endif %}
{% for db in additional_db_files %}
dbLoadRecords("{{ db.file }}", "{{ db.macros }}")
{% endfor %}
cd "$(TOP)"
dbLoadRecords("db/iocAdmin.db", "P={{prefix}},IOC={{prefix}}" )
dbLoadRecords("db/save_restoreStatus.db", "P={{prefix}},IOC={{name}}" )
# Setup autosave
set_savefile_path( "$(IOC_DATA)/$(IOC)/autosave" )
set_requestfile_path( "$(TOP)/autosave" )
save_restoreSet_status_prefix( "{{prefix}}:" )
save_restoreSet_IncompleteSetsOk( 1 )
save_restoreSet_DatedBackupFiles( 1 )
set_pass0_restoreFile( "$(IOC).sav" )
set_pass1_restoreFile( "$(IOC).sav" )
# Initialize the IOC and start processing records
iocInit()
# Start autosave backups
create_monitor_set( "$(IOC).req", 5, "" )
# All IOCs should dump some common info after initial startup.
< /reg/d/iocCommon/All/post_linux.cmd
asyn_standard_file.jinja2¶
{% for r in records%}
{{r}}
{% endfor %}
asyn_standard_record.jinja2¶
record({{record.record_type}}, "{{record.pvname}}") {
{% if record.long_description %}
# {{ record.long_description }}
{% endif %}
{% for alias in record.aliases %}
alias("{{alias}}")
{% endfor %}
{% block add_fields %}{% endblock %}
{% for f in record.fields%}
field({{f}}, "{{record.fields[f]}}")
{% endfor %}
{% if record.autosave['pass1'] %}
info(autosaveFields, "{{ record.autosave['pass1'] | sort | join(' ') }}")
{% endif %}
{% if record.autosave['pass0'] %}
info(autosaveFields_pass0, "{{ record.autosave['pass0'] | sort | join(' ') }}")
{% endif %}
{% if record.archive_settings %}
{% if record.archive_settings['method'] == 'scan' and record.archive_settings['seconds'] == 1 %}
info(archive, "{{ record.archive_settings['fields'] | join(' ') }}")
{% else %}
info(archive, "{{ record.archive_settings['method'] }} {{ record.archive_settings['seconds'] }}: {{ record.archive_settings['fields'] | join(' ') }}")
{% endif %}
{% endif %}
}