QtPYVCP - MACRO VAR Page - Persistent macro vars
03 Jan 2020 01:19 #153845
by Donb9261
QtPYVCP - MACRO VAR Page - Persistent macro vars was created by Donb9261
Hello all,
I have been plugging away, mostly pulling my hair out trying to come up with a meaningful solution to Volatile macro vars. As you know most macro vars outside those required by LCNC will only last as long as the control is up. If you shut down or lose power the file can become corrupted or worse simply dumped. With that in mind I set on a journey to find a way that makes sense and is easily added to your current VCP or maybe if everyone likes the idea, a widget can be made.
Currently, the code is good and fully functional. But it loses a lot due to a forced repeating of code. Not hard coding the UI has advantages and disadvantages.Regardless, if it works, don't fix it. I will try to DRY it up more as I go through coding iterations over time.
Here is what it looks like:
Now, I am working on a VCP I will release soon so the UI looks different than all others. But, it is the same. Kinda like woman. Lol. Ladies, I apologize in advance for my toxic masculine sense of humor.
So, for the meat and potatoes of how to use it. PLEASE PAY ATTENTION TO THE IMPORTS. All are a must have.
I have sufficiently commented all the code but if you have questions, feel free to hit me back. I like attention... My therapist says I need deep electro treatments to cure me.
First we need to build the UI in designer. Pretty simple. Need status labels for each lineEdit. I used VCPLineEedits but a standard line edit works fine. You can choose where in the group you want your macro params to start. Given I use Renishaw macros 500~599 are standard for their macros. They also use some 100's but I typically move them from the 100's to 500's on Fanuc controls so they are persistent. 100-199 on Fanuc are volatile. On Siemens you use GUD params. I will see how that can be done to help with those more comfortable with Siemens. Heidenhain is a whole other story.
According to LCNC docs, 31~5000 are volatile user variables. For me I typically use sections for specific purposes. 500~529 (Tool Setter Params) 530~559 (Touch Probe Params) 560~599 (Custom Macro for Coordinate System Rotations and Kinematic Euler Angles). 1000~1999 (Display and Program Settings) and so on. This is so custom and should be done to fit your needs.
In the pic you see the first page with each label showing the number of the macro variable and the acronym for what it means. That is also your choice. 500 - TPXR == Tool Probe X Basic Reference Position 503 - TPXC == Tool Probe X Calibration Position and so on,...
Each LineEdit has routine in main_window.py for getting the value and also monitoring the enterPressed event. Should work with both phy keyboards and virt keyboads.
Typing in the value and pressing enter will do a few things in the main_window.py file.
1. Store the value of the text
2. Set the parameter number to be changed
3. issue_mdi (#xxx = xxx)
4. call getMacroVars.
getMacroVars is complex but simple at the same time. Read the parameter file and parse to a python dictionary. Store the values and set each lineEdit to the value from the file. As long as you are using VCP 3.0 the file will auto save and reload. Currently, LCNC loads at start up uses memory to hold all values and rewrites the memory to disk at shutdown as long as it exits nicely.
This method ensures that at least once the file will be saved. I will be writing a routine that will rewrite the file at anytime the machine is idle for longer than 120 seconds. That way you always have a solid copy to rely on. Later, I will also implement shelve. Which will further ensure a persistent variable storage through power cycles or power loss. Shelve is a database for storage of small data sets. Works great but parsing back to the .var file is a pain.
setMacroVars will read in the parameter file, parse it and then write the file back out. Takes roughly 100ms. Easy peasy. It writes all values stored in the file. Not just macro vars. All offsets as well to keep the file linear and in the proper order. LCNC will crash if not in order. Anytime you change a Macro Var this is called and hard writes the var file.
That is about it really. The code looks scary but it is actually not.
Please make any suggestions or comments (be nice) as I think this will be a big help for more complex users. Especially for probers.
main_window.py - Cutting and pasting requires PyCharm or IntelliJ. Python can gotcha.
getMacroVars
setMacroVars
VCPLineEdit Calls - You need one for each var you use
My .var
I have been plugging away, mostly pulling my hair out trying to come up with a meaningful solution to Volatile macro vars. As you know most macro vars outside those required by LCNC will only last as long as the control is up. If you shut down or lose power the file can become corrupted or worse simply dumped. With that in mind I set on a journey to find a way that makes sense and is easily added to your current VCP or maybe if everyone likes the idea, a widget can be made.
Currently, the code is good and fully functional. But it loses a lot due to a forced repeating of code. Not hard coding the UI has advantages and disadvantages.Regardless, if it works, don't fix it. I will try to DRY it up more as I go through coding iterations over time.
Here is what it looks like:
Now, I am working on a VCP I will release soon so the UI looks different than all others. But, it is the same. Kinda like woman. Lol. Ladies, I apologize in advance for my toxic masculine sense of humor.
So, for the meat and potatoes of how to use it. PLEASE PAY ATTENTION TO THE IMPORTS. All are a must have.
I have sufficiently commented all the code but if you have questions, feel free to hit me back. I like attention... My therapist says I need deep electro treatments to cure me.
First we need to build the UI in designer. Pretty simple. Need status labels for each lineEdit. I used VCPLineEedits but a standard line edit works fine. You can choose where in the group you want your macro params to start. Given I use Renishaw macros 500~599 are standard for their macros. They also use some 100's but I typically move them from the 100's to 500's on Fanuc controls so they are persistent. 100-199 on Fanuc are volatile. On Siemens you use GUD params. I will see how that can be done to help with those more comfortable with Siemens. Heidenhain is a whole other story.
According to LCNC docs, 31~5000 are volatile user variables. For me I typically use sections for specific purposes. 500~529 (Tool Setter Params) 530~559 (Touch Probe Params) 560~599 (Custom Macro for Coordinate System Rotations and Kinematic Euler Angles). 1000~1999 (Display and Program Settings) and so on. This is so custom and should be done to fit your needs.
In the pic you see the first page with each label showing the number of the macro variable and the acronym for what it means. That is also your choice. 500 - TPXR == Tool Probe X Basic Reference Position 503 - TPXC == Tool Probe X Calibration Position and so on,...
Each LineEdit has routine in main_window.py for getting the value and also monitoring the enterPressed event. Should work with both phy keyboards and virt keyboads.
Typing in the value and pressing enter will do a few things in the main_window.py file.
1. Store the value of the text
2. Set the parameter number to be changed
3. issue_mdi (#xxx = xxx)
4. call getMacroVars.
getMacroVars is complex but simple at the same time. Read the parameter file and parse to a python dictionary. Store the values and set each lineEdit to the value from the file. As long as you are using VCP 3.0 the file will auto save and reload. Currently, LCNC loads at start up uses memory to hold all values and rewrites the memory to disk at shutdown as long as it exits nicely.
This method ensures that at least once the file will be saved. I will be writing a routine that will rewrite the file at anytime the machine is idle for longer than 120 seconds. That way you always have a solid copy to rely on. Later, I will also implement shelve. Which will further ensure a persistent variable storage through power cycles or power loss. Shelve is a database for storage of small data sets. Works great but parsing back to the .var file is a pain.
setMacroVars will read in the parameter file, parse it and then write the file back out. Takes roughly 100ms. Easy peasy. It writes all values stored in the file. Not just macro vars. All offsets as well to keep the file linear and in the proper order. LCNC will crash if not in order. Anytime you change a Macro Var this is called and hard writes the var file.
That is about it really. The code looks scary but it is actually not.
Please make any suggestions or comments (be nice) as I think this will be a big help for more complex users. Especially for probers.
main_window.py - Cutting and pasting requires PyCharm or IntelliJ. Python can gotcha.
import os
import linuxcnc
from qtpyvcp.widgets.form_widgets.main_window import VCPMainWindow
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QColor
from qtpy import QtWidgets, QtCore
from qtpyvcp.actions.base_actions import setTaskMode
from qtpyvcp.actions.machine_actions import issue_mdi
from qtpyvcp.plugins import getPlugin
from playsound import playsound
import resources
# Setup logging
from qtpyvcp.utilities import logger
LOG = logger.getLogger('qtpyvcp.' + __name__)
STATUS = getPlugin('status')
OFFSET = getPlugin('offsettable')
STAT = STATUS.stat
from qtpyvcp.utilities.info import Info
INFO = Info()
CMD = linuxcnc.command()
class MyMainWindow(VCPMainWindow):
"""Main window class for the VCP."""
def __init__(self, *args, **kwargs):
super(MyMainWindow, self).__init__(*args, **kwargs)
### Set Spindle Speed UI Controls Connections
self.mdi_s_code.released.connect(self.on_MdiSpeed_Released)
### OFFSETS PANNEL PAGE CONTROL SETUP
self.tool_offset_current_page.clicked.connect(self.buttonToolOffsetCurrentPage)
self.work_offset_current_page.clicked.connect(self.buttonWorkOffsetCurrentPage)
self.work_offset_change_page.clicked.connect(self.buttonWorkOffsetChangePage)
### OPERATIONS PANNEL PAGE CONTROL SETUP
self.gcodeProgramBtn.clicked.connect(self.buttonGcodeProgramChangePage)
self.gcodePlotBtn.clicked.connect(self.buttonGcodePlotChangePage)
self.workOffsetsBtn.clicked.connect(self.buttonWorkOffsetsChangePage)
self.toolOffsetsBtn.clicked.connect(self.buttonToolOffsetsChangePage)
### WORK OFFSETS PAGE CONTROL SETUP
self.g54_btn.clicked.connect(self.buttonWorkOffsetChangeG54)
self.g55_btn.clicked.connect(self.buttonWorkOffsetChangeG55)
self.g56_btn.clicked.connect(self.buttonWorkOffsetChangeG56)
self.g57_btn.clicked.connect(self.buttonWorkOffsetChangeG57)
self.g58_btn.clicked.connect(self.buttonWorkOffsetChangeG58)
self.g59_btn.clicked.connect(self.buttonWorkOffsetChangeG59)
self.g591_btn.clicked.connect(self.buttonWorkOffsetChangeG591)
self.g592_btn.clicked.connect(self.buttonWorkOffsetChangeG592)
self.g593_btn.clicked.connect(self.buttonWorkOffsetChangeG593)
### PENEL EFFECTS PROPERTIES
color = QColor(34, 35, 42)
shadowOperationsFrame = QGraphicsDropShadowEffect(color=(color), blurRadius=15, xOffset=3, yOffset=3)
shadowSpFrame = QGraphicsDropShadowEffect(color=(color), blurRadius=15, xOffset=3, yOffset=3)
shadowPositionsFrame = QGraphicsDropShadowEffect(color=(color), blurRadius=15, xOffset=3, yOffset=3)
shadowToolFrame = QGraphicsDropShadowEffect(color=(color), blurRadius=15, xOffset=3, yOffset=3)
shadowInfoFrame = QGraphicsDropShadowEffect(color=(color), blurRadius=15, xOffset=3, yOffset=3)
shadowFeedFrame = QGraphicsDropShadowEffect(color=(color), blurRadius=15, xOffset=3, yOffset=3)
### PENEL EFFECTS SETTER ### ISSUE HERE WIP
#self.operations_frame.setGraphicsEffect(shadowOperationsFrame)
#self.sp_frame.setGraphicsEffect(shadowSpFrame)
#self.positions_frame.setGraphicsEffect(shadowPositionsFrame)
#self.tool_frame.setGraphicsEffect(shadowToolFrame)
#self.info_frame.setGraphicsEffect(shadowInfoFrame)
#self.feed_frame.setGraphicsEffect(shadowFeedFrame)
### Setup connection to VCPLineEdit
self.lineNumber.returnPressed.connect(self.setStartingLineLabel)
### Connect run_from_here Btn to clear label after start
self.run_from_here.clicked.connect(self.clearStartLineLabel)
### Set up rapid override buutons
self.rapidZero.clicked.connect(self.buttonRapidZero)
self.rapidTwentyFive.clicked.connect(self.buttonRapidTwentyFive)
self.rapidFifty.clicked.connect(self.buttonRapidFifty)
self.rapidSeventyFive.clicked.connect(self.buttonRapidSeventyFive)
self.rapidHundred.clicked.connect(self.buttonRapidHundred)
### MACRO VARS BTN CONNECTIONS
self.macroVarsBtn.clicked.connect(self.buttonMacroVarsPage)
### Connect all lineEdits to their respective staging calls
self.var500.returnPressed.connect(self.var500Set)
self.var501.returnPressed.connect(self.var501Set)
self.var502.returnPressed.connect(self.var502Set)
self.var503.returnPressed.connect(self.var503Set)
self.var504.returnPressed.connect(self.var504Set)
self.var505.returnPressed.connect(self.var505Set)
self.var506.returnPressed.connect(self.var506Set)
self.var507.returnPressed.connect(self.var507Set)
self.var508.returnPressed.connect(self.var508Set)
self.var509.returnPressed.connect(self.var509Set)
self.var510.returnPressed.connect(self.var510Set)
self.var511.returnPressed.connect(self.var511Set)
self.var512.returnPressed.connect(self.var512Set)
self.var513.returnPressed.connect(self.var513Set)
# Intitialize some vars
self.paramNumber = ''
self.value = ''
# -------------------------------------------------------------------------
# BEGIN MDI SPEED SET UI BACK TO MAN MODE
# -------------------------------------------------------------------------
def on_MdiSpeed_Released(self):
self.man_mode_btn.setChecked(True)
# -------------------------------------------------------------------------
# BEGIN MDI SPEED SET UI BACK TO MAN MODE
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
# BEGIN OFFSETS PANEL PAGE BTNS
# -------------------------------------------------------------------------
def buttonToolOffsetCurrentPage(self):
tools_widget_prop = 0
self.offsets_stack_panel.setCurrentIndex(tools_widget_prop)
self.tool_offset_current_page.setStyleSheet('background-color: rgb(46,49,63)')
self.work_offset_change_page.setStyleSheet('background-color: rgb(17, 0, 30)')
self.work_offset_current_page.setStyleSheet('background-color: rgb(17, 0, 30)')
def buttonWorkOffsetCurrentPage(self):
tools_widget_prop = 1
self.offsets_stack_panel.setCurrentIndex(tools_widget_prop)
self.work_offset_current_page.setStyleSheet('background-color: rgb(46,49,63)')
self.tool_offset_current_page.setStyleSheet('background-color: rgb(17, 0, 30)')
self.work_offset_change_page.setStyleSheet('background-color: rgb(17, 0, 30)')
def buttonWorkOffsetChangePage(self):
tools_widget_prop = 2
self.offsets_stack_panel.setCurrentIndex(tools_widget_prop)
self.work_offset_change_page.setStyleSheet('background-color: rgb(46,49,63)')
self.tool_offset_current_page.setStyleSheet('background-color: rgb(17, 0, 30)')
self.work_offset_current_page.setStyleSheet('background-color: rgb(17, 0, 30)')
# -------------------------------------------------------------------------
# END OFFSETS PANEL PAGE BTNS
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
# BEGIN OPERATIONS PANEL PAGE BTNS
# -------------------------------------------------------------------------
def buttonGcodeProgramChangePage(self):
page = 0
self.operations_stacked_widget.setCurrentIndex(page)
self.gcodeProgramBtn.setStyleSheet('background-color: rgb(46,49,63)')
self.gcodePlotBtn.setStyleSheet('background-color: rgb(17, 0, 30)')
self.workOffsetsBtn.setStyleSheet('background-color: rgb(17, 0, 30)')
self.toolOffsetsBtn.setStyleSheet('background-color: rgb(17, 0, 30)')
self.macroVarsBtn.setStyleSheet('background-color: rgb(17, 0, 30)')
def buttonGcodePlotChangePage(self):
page = 2
self.operations_stacked_widget.setCurrentIndex(page)
self.gcodePlotBtn.setStyleSheet('background-color: rgb(46,49,63)')
self.gcodeProgramBtn.setStyleSheet('background-color: rgb(17, 0, 30)')
self.workOffsetsBtn.setStyleSheet('background-color: rgb(17, 0, 30)')
self.toolOffsetsBtn.setStyleSheet('background-color: rgb(17, 0, 30)')
self.macroVarsBtn.setStyleSheet('background-color: rgb(17, 0, 30)')
def buttonWorkOffsetsChangePage(self):
page = 1
self.operations_stacked_widget.setCurrentIndex(page)
self.workOffsetsBtn.setStyleSheet('background-color: rgb(46,49,63)')
self.gcodeProgramBtn.setStyleSheet('background-color: rgb(17, 0, 30)')
self.gcodePlotBtn.setStyleSheet('background-color: rgb(17, 0, 30)')
self.toolOffsetsBtn.setStyleSheet('background-color: rgb(17, 0, 30)')
self.macroVarsBtn.setStyleSheet('background-color: rgb(17, 0, 30)')
def buttonToolOffsetsChangePage(self):
page = 3
self.operations_stacked_widget.setCurrentIndex(page)
self.toolOffsetsBtn.setStyleSheet('background-color: rgb(46,49,63)')
self.gcodeProgramBtn.setStyleSheet('background-color: rgb(17, 0, 30)')
self.gcodePlotBtn.setStyleSheet('background-color: rgb(17, 0, 30)')
self.workOffsetsBtn.setStyleSheet('background-color: rgb(17, 0, 30)')
self.macroVarsBtn.setStyleSheet('background-color: rgb(17, 0, 30)')
def buttonMacroVarsPage(self):
self.getMacroVars()
page = 4
self.operations_stacked_widget.setCurrentIndex(page)
self.getMacroVars()
self.macroVarsBtn.setStyleSheet('background-color: rgb(46,49,63)')
self.toolOffsetsBtn.setStyleSheet('background-color: rgb(17, 0, 30)')
self.gcodeProgramBtn.setStyleSheet('background-color: rgb(17, 0, 30)')
self.gcodePlotBtn.setStyleSheet('background-color: rgb(17, 0, 30)')
self.workOffsetsBtn.setStyleSheet('background-color: rgb(17, 0, 30)')
# -------------------------------------------------------------------------
# END OPERATIONS PANEL PAGE BTNS
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
# BEGIN Get MACRO VARS
# -------------------------------------------------------------------------
def getMacroVars(self):
# Get the file name
file_name = INFO.getParameterFile()
self.parameter_file = None
parameters = {}
# Set the path
if file_name:
self.parameter_file = os.path.join(os.path.dirname(os.path.realpath(file_name)), file_name)
# If we find the file, parse it out to dict
if self.parameter_file:
with open(file_name, 'r') as read_obj:
for line in read_obj:
temp = line.split()
param = int(temp[0])
data = float(temp[1])
if param < 6000:
for p in str(param):
param_int = str(param)
parameters[param_int] = str(data)
# Close the file
read_obj.close()
# Update each lineEdit for the macro vars from the dict
for p in parameters.items():
if p[0] == '500':
self.var500.setText(p[1])
if p[0] == '501':
self.var501.setText(p[1])
if p[0] == '502':
self.var502.setText(p[1])
if p[0] == '503':
self.var503.setText(p[1])
if p[0] == '504':
self.var504.setText(p[1])
if p[0] == '505':
self.var505.setText(p[1])
if p[0] == '506':
self.var506.setText(p[1])
if p[0] == '507':
self.var507.setText(p[1])
if p[0] == '508':
self.var508.setText(p[1])
if p[0] == '509':
self.var509.setText(p[1])
if p[0] == '510':
self.var510.setText(p[1])
if p[0] == '511':
self.var511.setText(p[1])
if p[0] == '512':
self.var512.setText(p[1])
if p[0] == '513':
self.var513.setText(p[1])
if p[0] == '514':
self.var514.setText(p[1])
if p[0] == '515':
self.var515.setText(p[1])
if p[0] == '516':
self.var516.setText(p[1])
if p[0] == '517':
self.var517.setText(p[1])
if p[0] == '518':
self.var518.setText(p[1])
if p[0] == '519':
self.var519.setText(p[1])
if p[0] == '520':
self.var520.setText(p[1])
if p[0] == '521':
self.var522.setText(p[1])
if p[0] == '523':
self.var523.setText(p[1])
if p[0] == '524':
self.var524.setText(p[1])
if p[0] == '525':
self.var525.setText(p[1])
if p[0] == '526':
self.var526.setText(p[1])
if p[0] == '527':
self.var527.setText(p[1])
if p[0] == '528':
self.var528.setText(p[1])
if p[0] == '529':
self.var529.setText(p[1])
# -------------------------------------------------------------------------
# END SET MACRO VARS
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
# BEGIN VAR INPUT FIELD CALLS
# -------------------------------------------------------------------------
### Each will set the local vars for their respective lineEdit
### The issue an MDI cmd to set the vars in the LCNC buffer
### Then a call to the UI controller for the macro var lineEdits to update vals
######TODO - Add a way for issue_mdi to know when to update the UI from the MDI Entry
######in the UI. This works but if you use the MDI entry or GCODE to set a macro var
######the lineEdits will not automatically reset their values unless the param btn is pressed
######or the file is reloaded via all other means.
def var500Set(self):
self.paramNumber = '500'
self.value = self.var500.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
def var501Set(self):
self.paramNumber = '501'
self.value = self.var501.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
def var502Set(self):
self.paramNumber = '502'
self.value = self.var502.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
def var503Set(self):
self.paramNumber = '503'
self.value = self.var503.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
def var504Set(self):
self.paramNumber = '504'
self.value = self.var504.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
def var505Set(self):
self.paramNumber = '505'
self.value = self.var505.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
def var506Set(self):
self.paramNumber = '506'
self.value = self.var506.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
def var507Set(self):
self.paramNumber = '507'
self.value = self.var507.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
def var508Set(self):
self.paramNumber = '508'
self.value = self.var508.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
def var509Set(self):
self.paramNumber = '509'
self.value = self.var509.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
def var510Set(self):
self.paramNumber = '510'
self.value = self.var510.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
def var511Set(self):
self.paramNumber = '511'
self.value = self.var511.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
def var512Set(self):
self.paramNumber = '512'
self.value = self.var512.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
def var513Set(self):
self.paramNumber = '513'
self.value = self.var513.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
# -------------------------------------------------------------------------
# END VAR INPUT FIELD CALLS
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
# BEGIN SET MACRO VARS
# -------------------------------------------------------------------------
def setMacroVars(self, paramNumber, value):
# Get the parameter file
file_name = INFO.getParameterFile()
self.parameter_file = None
# Set up locals
parameters2 = []
paramNumberIn = paramNumber
valueIn = value
# Make sure we have the parameter file and set the path
if file_name:
self.parameter_file = os.path.join(os.path.dirname(os.path.realpath(file_name)), file_name)
# If we have the file let's start reading
if self.parameter_file:
# OPens the file in read mode
with open(file_name, 'r') as update_obj:
for line in update_obj:
plist = []
temp = line.split()
param = int(temp[0])
plist.append(param)
data = float(temp[1])
clist = param
# Make sure we do not read past LCNC allowed param nums
if param < 6000:
for p in plist:
paramlist = {}
clist2 = str(clist)
# If there is a value and param to modify
if clist == int(paramNumberIn):
paramlist[paramNumberIn] = valueIn
# Otherwise just write the local mem list as found
elif clist != int(paramNumberIn):
paramlist[clist2] = str(data)
clist += 1
# Add each to the param mem list
parameters2.append(paramlist)
print(paramlist)
# Close the file
update_obj.close()
# Reopen the file in write mode
with open(file_name, 'w') as write_obj:
# Set up key value pairs for file write
for p in parameters2:
key = ''
value = ''
for k in p.keys():
key = k
for v in p.values():
value = v
kv = (key + '\t' + value + '\n')
# Write each line one by one to complete the file. All vars are updated 500~last one
write_obj.write(kv)
# Close the file
write_obj.close()
# Update the LineEdit fields in the UI
self.getMacroVars()
# Call for the offset tables(parameter file) reload
OFFSET.reloadOffsetTable()
# -------------------------------------------------------------------------
# BEGIN SET MACRO VARS
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
# BEGIN MAX VEL OVERRIDE Button Group UI Contoller
# -------------------------------------------------------------------------
def buttonRapidZero(self):
smv = '0'
self.rapidZero.setChecked(True)
self.rapidTwentyFive.setChecked(False)
self.rapidFifty.setChecked(False)
self.rapidSeventyFive.setChecked(False)
self.rapidHundred.setChecked(False)
self.rapidOVRLabel.setText(smv)
def buttonRapidTwentyFive(self):
c_val = ((INFO.maxVelocity() * 1000) / 25.4) / 60 # Get current MV static param from ini
set_val = c_val * .25
fval = "%.1f" % set_val
self.rapidZero.setChecked(False)
self.rapidTwentyFive.setChecked(True)
self.rapidFifty.setChecked(False)
self.rapidSeventyFive.setChecked(False)
self.rapidHundred.setChecked(False)
self.rapidOVRLabel.setText(fval)
def buttonRapidFifty(self):
c_val = ((INFO.maxVelocity() * 1000) / 25.4) / 60 # Get current MV static param from ini
set_val = c_val * .5
fval = "%.1f" % set_val
self.rapidZero.setChecked(False)
self.rapidTwentyFive.setChecked(False)
self.rapidFifty.setChecked(True)
self.rapidSeventyFive.setChecked(False)
self.rapidHundred.setChecked(False)
self.rapidOVRLabel.setText(fval)
def buttonRapidSeventyFive(self):
c_val = ((INFO.maxVelocity() * 1000) / 25.4) / 60 # Get current MV static param from ini
set_val = c_val * .75
fval = "%.1f" % set_val
self.rapidZero.setChecked(False)
self.rapidTwentyFive.setChecked(False)
self.rapidFifty.setChecked(False)
self.rapidSeventyFive.setChecked(True)
self.rapidHundred.setChecked(False)
self.rapidOVRLabel.setText(fval)
def buttonRapidHundred(self):
c_val = ((INFO.maxVelocity() * 1000) / 25.4) / 60 # Get current MV static param from ini
set_val = c_val * 1
fval = "%.1f" % set_val
self.rapidZero.setChecked(False)
self.rapidTwentyFive.setChecked(False)
self.rapidFifty.setChecked(False)
self.rapidSeventyFive.setChecked(False)
self.rapidHundred.setChecked(True)
self.rapidOVRLabel.setText(fval)
# -------------------------------------------------------------------------
# END MAX VEL OVERRIDE Button Group UI Contoller
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
# BEGIN WO BTN UI CONTROLLER
# -------------------------------------------------------------------------
def buttonWorkOffsetChangeG54(self):
self.g54_btn.setChecked(True)
self.g55_btn.setChecked(False)
self.g56_btn.setChecked(False)
self.g57_btn.setChecked(False)
self.g58_btn.setChecked(False)
self.g59_btn.setChecked(False)
self.g591_btn.setChecked(False)
self.g592_btn.setChecked(False)
self.g593_btn.setChecked(False)
def buttonWorkOffsetChangeG55(self):
self.g54_btn.setChecked(False)
self.g55_btn.setChecked(True)
self.g56_btn.setChecked(False)
self.g57_btn.setChecked(False)
self.g58_btn.setChecked(False)
self.g59_btn.setChecked(False)
self.g591_btn.setChecked(False)
self.g592_btn.setChecked(False)
self.g593_btn.setChecked(False)
def buttonWorkOffsetChangeG56(self):
self.g54_btn.setChecked(False)
self.g55_btn.setChecked(False)
self.g56_btn.setChecked(True)
self.g57_btn.setChecked(False)
self.g58_btn.setChecked(False)
self.g59_btn.setChecked(False)
self.g591_btn.setChecked(False)
self.g592_btn.setChecked(False)
self.g593_btn.setChecked(False)
def buttonWorkOffsetChangeG57(self):
self.g54_btn.setChecked(False)
self.g55_btn.setChecked(False)
self.g56_btn.setChecked(False)
self.g57_btn.setChecked(True)
self.g58_btn.setChecked(False)
self.g59_btn.setChecked(False)
self.g591_btn.setChecked(False)
self.g592_btn.setChecked(False)
self.g593_btn.setChecked(False)
def buttonWorkOffsetChangeG58(self):
self.g54_btn.setChecked(False)
self.g55_btn.setChecked(False)
self.g56_btn.setChecked(False)
self.g57_btn.setChecked(False)
self.g58_btn.setChecked(True)
self.g59_btn.setChecked(False)
self.g591_btn.setChecked(False)
self.g592_btn.setChecked(False)
self.g593_btn.setChecked(False)
def buttonWorkOffsetChangeG59(self):
self.g54_btn.setChecked(False)
self.g55_btn.setChecked(False)
self.g56_btn.setChecked(False)
self.g57_btn.setChecked(False)
self.g58_btn.setChecked(False)
self.g59_btn.setChecked(True)
self.g591_btn.setChecked(False)
self.g592_btn.setChecked(False)
self.g593_btn.setChecked(False)
def buttonWorkOffsetChangeG591(self):
self.g54_btn.setChecked(False)
self.g55_btn.setChecked(False)
self.g56_btn.setChecked(False)
self.g57_btn.setChecked(False)
self.g58_btn.setChecked(False)
self.g59_btn.setChecked(False)
self.g591_btn.setChecked(True)
self.g592_btn.setChecked(False)
self.g593_btn.setChecked(False)
def buttonWorkOffsetChangeG592(self):
self.g54_btn.setChecked(False)
self.g55_btn.setChecked(False)
self.g56_btn.setChecked(False)
self.g57_btn.setChecked(False)
self.g58_btn.setChecked(False)
self.g59_btn.setChecked(False)
self.g591_btn.setChecked(False)
self.g592_btn.setChecked(True)
self.g593_btn.setChecked(False)
def buttonWorkOffsetChangeG593(self):
self.g54_btn.setChecked(False)
self.g55_btn.setChecked(False)
self.g56_btn.setChecked(False)
self.g57_btn.setChecked(False)
self.g58_btn.setChecked(False)
self.g59_btn.setChecked(False)
self.g591_btn.setChecked(False)
self.g592_btn.setChecked(False)
self.g593_btn.setChecked(True)
# -------------------------------------------------------------------------
# END WO BTN UI CONTROLLER
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
# BEGIN RUN FROM HERE SETUP
# -------------------------------------------------------------------------
def setStartingLineLabel(self):
# Set variable to the VCPLineEdit Text Value
line_number = self.lineNumber.text()
# Set StatusLabel to alert where the program will start
self.run_from_here.setText('RUN FROM LINE ' + line_number)
# Set the actionName property of the Run From Line Btn
self.run_from_here.setProperty('actionName', 'program.run:' + line_number)
self.run_from_here.setChecked(True)
# Play a sound to alert when ready
playsound('/home/don/Downloads/bvmtnf_ui-21.wav')
self.lineNumber.setText('')
def clearStartLineLabel(self):
self.run_from_here.setText('RUN FROM LINE')
self.run_from_here.setChecked(False)
# -------------------------------------------------------------------------
# END RUN FROM HERE SETUP
# -------------------------------------------------------------------------
getMacroVars
# -------------------------------------------------------------------------
# BEGIN Get MACRO VARS
# -------------------------------------------------------------------------
def getMacroVars(self):
# Get the file name
file_name = INFO.getParameterFile()
self.parameter_file = None
parameters = {}
# Set the path
if file_name:
self.parameter_file = os.path.join(os.path.dirname(os.path.realpath(file_name)), file_name)
# If we find the file, parse it out to dict
if self.parameter_file:
with open(file_name, 'r') as read_obj:
for line in read_obj:
temp = line.split()
param = int(temp[0])
data = float(temp[1])
if param < 6000:
for p in str(param):
param_int = str(param)
parameters[param_int] = str(data)
# Close the file
read_obj.close()
# Update each lineEdit for the macro vars from the dict
for p in parameters.items():
if p[0] == '500':
self.var500.setText(p[1])
if p[0] == '501':
self.var501.setText(p[1])
if p[0] == '502':
self.var502.setText(p[1])
if p[0] == '503':
self.var503.setText(p[1])
if p[0] == '504':
self.var504.setText(p[1])
if p[0] == '505':
self.var505.setText(p[1])
if p[0] == '506':
self.var506.setText(p[1])
if p[0] == '507':
self.var507.setText(p[1])
if p[0] == '508':
self.var508.setText(p[1])
if p[0] == '509':
self.var509.setText(p[1])
if p[0] == '510':
self.var510.setText(p[1])
if p[0] == '511':
self.var511.setText(p[1])
if p[0] == '512':
self.var512.setText(p[1])
if p[0] == '513':
self.var513.setText(p[1])
if p[0] == '514':
self.var514.setText(p[1])
if p[0] == '515':
self.var515.setText(p[1])
if p[0] == '516':
self.var516.setText(p[1])
if p[0] == '517':
self.var517.setText(p[1])
if p[0] == '518':
self.var518.setText(p[1])
if p[0] == '519':
self.var519.setText(p[1])
if p[0] == '520':
self.var520.setText(p[1])
if p[0] == '521':
self.var522.setText(p[1])
if p[0] == '523':
self.var523.setText(p[1])
if p[0] == '524':
self.var524.setText(p[1])
if p[0] == '525':
self.var525.setText(p[1])
if p[0] == '526':
self.var526.setText(p[1])
if p[0] == '527':
self.var527.setText(p[1])
if p[0] == '528':
self.var528.setText(p[1])
if p[0] == '529':
self.var529.setText(p[1])
# -------------------------------------------------------------------------
# END GET MACRO VARS
# -------------------------------------------------------------------------
setMacroVars
# -------------------------------------------------------------------------
# BEGIN SET MACRO VARS
# -------------------------------------------------------------------------
def setMacroVars(self, paramNumber, value):
# Get the parameter file
file_name = INFO.getParameterFile()
self.parameter_file = None
# Set up locals
parameters2 = []
paramNumberIn = paramNumber
valueIn = value
# Make sure we have the parameter file and set the path
if file_name:
self.parameter_file = os.path.join(os.path.dirname(os.path.realpath(file_name)), file_name)
# If we have the file let's start reading
if self.parameter_file:
# OPens the file in read mode
with open(file_name, 'r') as update_obj:
for line in update_obj:
plist = []
temp = line.split()
param = int(temp[0])
plist.append(param)
data = float(temp[1])
clist = param
# Make sure we do not read past LCNC allowed param nums
if param < 6000:
for p in plist:
paramlist = {}
clist2 = str(clist)
# If there is a value and param to modify
if clist == int(paramNumberIn):
paramlist[paramNumberIn] = valueIn
# Otherwise just write the local mem list as found
elif clist != int(paramNumberIn):
paramlist[clist2] = str(data)
clist += 1
# Add each to the param mem list
parameters2.append(paramlist)
print(paramlist)
# Close the file
update_obj.close()
# Reopen the file in write mode
with open(file_name, 'w') as write_obj:
# Set up key value pairs for file write
for p in parameters2:
key = ''
value = ''
for k in p.keys():
key = k
for v in p.values():
value = v
kv = (key + '\t' + value + '\n')
# Write each line one by one to complete the file. All vars are updated 500~last one
write_obj.write(kv)
# Close the file
write_obj.close()
# Update the LineEdit fields in the UI
self.getMacroVars()
# Call for the offset tables(parameter file) reload
OFFSET.reloadOffsetTable()
# -------------------------------------------------------------------------
# END SET MACRO VARS
# -------------------------------------------------------------------------
VCPLineEdit Calls - You need one for each var you use
# -------------------------------------------------------------------------
# BEGIN VAR INPUT FIELD CALLS
# -------------------------------------------------------------------------
### Each will set the local vars for their respective lineEdit
### The issue an MDI cmd to set the vars in the LCNC buffer
### Then a call to the UI controller for the macro var lineEdits to update vals
######TODO - Add a way for issue_mdi to know when to update the UI from the MDI Entry
######in the UI. This works but if you use the MDI entry or GCODE to set a macro var
######the lineEdits will not automatically reset their values unless the param btn is pressed
######or the file is reloaded via all other means.
def var500Set(self):
self.paramNumber = '500'
self.value = self.var500.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
def var501Set(self):
self.paramNumber = '501'
self.value = self.var501.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
def var502Set(self):
self.paramNumber = '502'
self.value = self.var502.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
def var503Set(self):
self.paramNumber = '503'
self.value = self.var503.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
def var504Set(self):
self.paramNumber = '504'
self.value = self.var504.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
def var505Set(self):
self.paramNumber = '505'
self.value = self.var505.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
def var506Set(self):
self.paramNumber = '506'
self.value = self.var506.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
def var507Set(self):
self.paramNumber = '507'
self.value = self.var507.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
def var508Set(self):
self.paramNumber = '508'
self.value = self.var508.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
def var509Set(self):
self.paramNumber = '509'
self.value = self.var509.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
def var510Set(self):
self.paramNumber = '510'
self.value = self.var510.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
def var511Set(self):
self.paramNumber = '511'
self.value = self.var511.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
def var512Set(self):
self.paramNumber = '512'
self.value = self.var512.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
def var513Set(self):
self.paramNumber = '513'
self.value = self.var513.text()
issue_mdi('#' + self.paramNumber + '=' + self.value)
self.setMacroVars(self.paramNumber, self.value)
# -------------------------------------------------------------------------
# END VAR INPUT FIELD CALLS
# -------------------------------------------------------------------------
My .var
500 567.234500
501 1.000000
502 2222.222200
503 3333.333300
504 4444.444400
505 5555.555500
506 6666.666600
507 7777.777700
508 8888.888800
509 9999.999900
510 1010.101000
511 1111.111100
512 1212.121200
513 1313.131300
514 0.000000
515 0.000000
516 0.000000
517 0.000000
518 0.000000
519 0.000000
520 0.000000
521 0.000000
522 0.000000
523 0.000000
524 0.000000
525 0.000000
526 0.000000
527 0.000000
528 0.000000
529 0.000000
530 0.000000
5161 0.000000
5162 0.000000
5163 0.000000
5164 0.000000
5165 0.000000
5166 0.000000
5167 0.000000
5168 0.000000
5169 0.000000
5181 0.000000
5182 0.000000
5183 0.000000
5184 0.000000
5185 0.000000
5186 0.000000
5187 0.000000
5188 0.000000
5189 0.000000
5210 0.000000
5211 0.000000
5212 0.000000
5213 0.000000
5214 0.000000
5215 0.000000
5216 0.000000
5217 0.000000
5218 0.000000
5219 0.000000
5220 1.000000
5221 -11.000000
5222 -12.000000
5223 -13.000000
5224 0.000000
5225 5.000000
5226 6.000000
5227 7.000000
5228 8.000000
5229 9.000000
5230 0.000000
5241 3.123400
5242 2.000000
5243 3.000000
5244 4.000000
5245 5.000000
5246 6.000000
5247 7.000000
5248 8.000000
5249 9.000000
5250 55.000000
5261 1.000000
5262 2.000000
5263 3.000000
5264 4.000000
5265 5.000000
5266 6.000000
5267 7.000000
5268 8.000000
5269 9.000000
5270 65.000000
5281 1.000000
5282 2.000000
5283 3.000000
5284 4.000000
5285 5.000000
5286 6.000000
5287 7.000000
5288 8.000000
5289 9.000000
5290 75.000000
5301 1.000000
5302 2.000000
5303 3.000000
5304 4.000000
5305 5.000000
5306 6.000000
5307 7.000000
5308 8.000000
5309 9.000000
5310 85.000000
5321 0.000000
5322 0.000000
5323 0.000000
5324 0.000000
5325 0.000000
5326 0.000000
5327 0.000000
5328 0.000000
5329 0.000000
5330 0.000000
5341 0.000000
5342 0.000000
5343 0.000000
5344 0.000000
5345 0.000000
5346 0.000000
5347 0.000000
5348 0.000000
5349 0.000000
5350 0.000000
5361 0.000000
5362 0.000000
5363 0.000000
5364 0.000000
5365 0.000000
5366 0.000000
5367 0.000000
5368 0.000000
5369 0.000000
5370 0.000000
5381 0.000000
5382 0.000000
5383 0.000000
5384 0.000000
5385 0.000000
5386 0.000000
5387 0.000000
5388 0.000000
5389 0.000000
5390 0.000000
Attachments:
Please Log in or Create an account to join the conversation.
03 Jan 2020 01:35 #153846
by Leon82
Replied by Leon82 on topic QtPYVCP - MACRO VAR Page - Persistent macro vars
I like all your ideas. I lack the coding knowledge to do it
Please Log in or Create an account to join the conversation.
03 Jan 2020 01:48 #153847
by Donb9261
Replied by Donb9261 on topic QtPYVCP - MACRO VAR Page - Persistent macro vars
LOL! Me too. But thanks.
Please Log in or Create an account to join the conversation.
03 Jan 2020 01:49 #153848
by Donb9261
Replied by Donb9261 on topic QtPYVCP - MACRO VAR Page - Persistent macro vars
Heck if you have ideas, I am sure I can work with you to develop them. Share and share alike.
Please Log in or Create an account to join the conversation.
03 Jan 2020 02:11 #153849
by Leon82
+ or - Input button for offsets.
I tried with an mdibutton and offset label but it doesn't work
Replied by Leon82 on topic QtPYVCP - MACRO VAR Page - Persistent macro vars
Heck if you have ideas, I am sure I can work with you to develop them. Share and share alike.
+ or - Input button for offsets.
I tried with an mdibutton and offset label but it doesn't work
Please Log in or Create an account to join the conversation.
03 Jan 2020 11:12 #153885
by Donb9261
Replied by Donb9261 on topic QtPYVCP - MACRO VAR Page - Persistent macro vars
doable but a challenge based on how you play it. If you you increment by the smallest value .0001" or .001mm only it may make it a pain. I suppose a third btn for inc size would allow you to set .0001, .001, .01, ,1, 1. inc.
Let me wrap it in code and see. May be a four button setup to add a save button. This could then call a version of my macro save function to write it and reload once save is pressed.
Let me wrap it in code and see. May be a four button setup to add a save button. This could then call a version of my macro save function to write it and reload once save is pressed.
Please Log in or Create an account to join the conversation.
08 Jan 2020 16:43 #154317
by andypugh
Replied by andypugh on topic QtPYVCP - MACRO VAR Page - Persistent macro vars
One thing worth pointing out, that doesn't particularly jump out in the docs, is that any numbered parameter that is added to the .var file will become persistent.
I wonder how hard it would be to make named parameters work the same way?
I wonder how hard it would be to make named parameters work the same way?
Please Log in or Create an account to join the conversation.
08 Jan 2020 18:23 #154332
by partec
Replied by partec on topic QtPYVCP - MACRO VAR Page - Persistent macro vars
It would be desirable to load and save parameters from and to the Linuxcnc.var File
then set actual parameters for use in grinding macro may be in a Qtvcp tab in Touchy
may be parallel use of a extra Qtvcp CamView window
jog with relevant joint to position behind workpiece, press yellow button "teach in behind workpiece"
jog with relevant joint to position ahead of workpiece, press yellow button "teach in ahead of workpiece"
jog with relevant joint to position over top of workpiece, press yellow button "teach in secure top of workpiece"
input grinding allowance some way, press yellow button "teach in grinding allowance of workpiece"
and so on for all needed parameters
then with relevant macro press start button for grinding
forum.linuxcnc.org/forum/search?searchuser=partec&childforums=1
then set actual parameters for use in grinding macro may be in a Qtvcp tab in Touchy
may be parallel use of a extra Qtvcp CamView window
jog with relevant joint to position behind workpiece, press yellow button "teach in behind workpiece"
jog with relevant joint to position ahead of workpiece, press yellow button "teach in ahead of workpiece"
jog with relevant joint to position over top of workpiece, press yellow button "teach in secure top of workpiece"
input grinding allowance some way, press yellow button "teach in grinding allowance of workpiece"
and so on for all needed parameters
then with relevant macro press start button for grinding
forum.linuxcnc.org/forum/search?searchuser=partec&childforums=1
Please Log in or Create an account to join the conversation.
13 Jan 2020 14:11 #154759
by Donb9261
Replied by Donb9261 on topic QtPYVCP - MACRO VAR Page - Persistent macro vars
Any value between 30-5000 added to the .var file will become persistent once added. Named parameters are in-memory only and cannot be saved into the .var file from my understanding nor should they be. You could use a function to temp store the value into a variable not stored in the .var file and then place that value into a text file and then write function to recall it from the file back into the temp variable for use again but this becomes redundant.
Named parameters are best suited for internal O calls only for descriptive purposes. If you plan to store them by convention you should use a valid variable number in your .var file and provide a comment in you macro above each call to describe the use so that in many cases you can easily transfer the macro with minimal changes to and other cnc controller that uses a Macro B typing system such as Fanuc. Siemens would be the exception as Siemens uses modified Pascal(YUCK!) for macros.
You can if I understand the docs, use named params in a py file but do not know how and as stated above would not follow convention so I would never seek to know how.
Hope that helps.
Don San
Named parameters are best suited for internal O calls only for descriptive purposes. If you plan to store them by convention you should use a valid variable number in your .var file and provide a comment in you macro above each call to describe the use so that in many cases you can easily transfer the macro with minimal changes to and other cnc controller that uses a Macro B typing system such as Fanuc. Siemens would be the exception as Siemens uses modified Pascal(YUCK!) for macros.
You can if I understand the docs, use named params in a py file but do not know how and as stated above would not follow convention so I would never seek to know how.
Hope that helps.
Don San
The following user(s) said Thank You: anfänger
Please Log in or Create an account to join the conversation.
Time to create page: 0.760 seconds