#!/usr/bin/env python3 # Qtvcp # # Copyright (c) 2017 Chris Morley # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # import os import linuxcnc from qtpy.QtWidgets import QWidget from qtpy.QtCore import Property from qtvcp.widgets.widget_baseclass import _HalWidgetBase from qtvcp.core import Status, Info from qtvcp import logger # Instiniate the libraries with global reference # STATUS gives us status messages from linuxcnc # LOG is for running code logging STATUS = Status() INFO = Info() LOG = logger.getLogger(__name__) class StateEnableGridLayout(QWidget, _HalWidgetBase): def __init__(self, parent=None): super(StateEnableGridLayout, self).__init__(parent) # if 'NO_FORCE_HOMING' is true, MDI commands are allowed before homing. self.inifile = os.environ.get('INI_FILE_NAME', '/dev/null') self.ini = linuxcnc.ini(self.inifile) self.no_home_required = self.ini.getbool("TRAJ", "NO_FORCE_HOMING", fallback=False) self.is_on = False self.is_homed = False self.is_idle = False self.is_not_idle = False self.setEnabled(False) def _hal_init(self): STATUS.connect('state-estop', lambda w: self.setEnabled(False)) if self.is_on: STATUS.connect('state-off', lambda w: self.setEnabled(False)) if self.is_homed: STATUS.connect('all-homed', lambda w: self.setEnabled(True)) if self.is_idle: STATUS.connect('interp-run', lambda w: self.setEnabled(False)) elif self.is_not_idle: STATUS.connect('interp-run', lambda w: self.setEnabled(True)) if not (self.is_idle or self.is_not_idle or self.is_on or self.is_homed): STATUS.connect('state-estop-reset', lambda w: self.setEnabled(True)) else: STATUS.connect('interp-idle', self.idle_check) def idle_check(self, w): state = True if self.is_homed: state = state and (STATUS.is_all_homed() or self.no_home_required) if self.is_on: state = state and STATUS.machine_is_on() if self.is_idle: state = state and True elif self.is_not_idle: self.setEnabled(False) return self.setEnabled(state) # property getter/setters # machine is on status def set_is_on(self, data): self.is_on = data def get_is_on(self): return self.is_on def reset_is_on(self): self.is_on = False is_on_status = Property(bool, get_is_on, set_is_on, reset_is_on) # machine is idle status def set_is_idle(self, data): self.is_idle = data if (data and self.is_not_idle): self.is_not_idle = False def get_is_idle(self): return self.is_idle def reset_is_idle(self): self.is_idle = False is_idle_status = Property(bool, get_is_idle, set_is_idle, reset_is_idle) # machine is not idle status def set_is_not_idle(self, data): self.is_not_idle = data if (data and self.is_idle): self.is_idle = False def get_is_not_idle(self): return self.is_not_idle def reset_is_not_idle(self): self.is_not_idle = False is_not_idle_status = Property(bool, get_is_not_idle, set_is_not_idle, reset_is_not_idle) # machine is homed status def set_is_homed(self, data): self.is_homed = data def get_is_homed(self): return self.is_homed def reset_is_homed(self): self.is_homed = False is_homed_status = Property(bool, get_is_homed, set_is_homed, reset_is_homed) class JointEnableWidget(QWidget, _HalWidgetBase): def __init__(self, parent=None): super(JointEnableWidget, self).__init__(parent) self.joint = 1 self.axis = 'A' self.joint_mode = False self.axis_mode = False self.if_joint_available = False self.if_axis_available = True def _hal_init(self): if self.if_joint_available: if not self.joint in INFO.AVAILABLE_JOINTS: self.setVisible(False) elif self.if_axis_available: if not self.axis.upper() in INFO.AVAILABLE_AXES: self.setVisible(False) if self.joint_mode or self.axis_mode: STATUS.connect('motion-mode-changed', lambda w,data: self.modeChanged(data)) def modeChanged(self, mode): if mode == STATUS.is_joint_mode(): self.setVisible(self.joint_mode) else: self.setVisible(self.axis_mode) ######################################################################### # This is how designer can interact with our widget properties. # designer will show the Property properties in the editor # it will use the get set and reset calls to do those actions # # _toggle_properties makes it so we can only select one option ######################################################################## def _toggle_properties(self, picked): data = ('only_in_axis_mode', 'only_in_joint_mode', ) for i in data: if not i == picked: self[i] = False def set_joint(self, data): self.joint = data def get_joint(self): return self.joint def reset_joint(self): self.joint = -1 def set_axis(self, data): if data.upper() in('X','Y','Z','A','B','C','U','V','W'): self.axis = data.upper() def get_axis(self): return self.axis def reset_axis(self): self.axis = 'X' def set_joint_mode(self, data): self.joint_mode = data if data: self._toggle_properties('only_in_joint_mode') def get_joint_mode(self): return self.joint_mode def reset_joint_mode(self): self.joint_mode = False def set_axis_mode(self, data): self.axis_mode = data if data: self._toggle_properties('only_in_axis_mode') def get_axis_mode(self): return self.axis_mode def reset_axis_mode(self): self.axis_mode = False def set_axis_available(self, data): self.if_axis_available = data def get_axis_available(self): return self.if_axis_available def reset_axis_available(self): self.if_axis_available = False def set_joint_available(self, data): self.if_joint_available = data def get_joint_available(self): return self.if_joint_available def reset_joint_available(self): self.if_joint_available = False joint_number = Property(int, get_joint, set_joint, reset_joint) axis_letter = Property(str, get_axis, set_axis, reset_axis) only_in_joint_mode = Property(bool, get_joint_mode, set_joint_mode, reset_joint_mode) only_in_axis_mode = Property(bool, get_axis_mode, set_axis_mode, reset_axis_mode) only_if_axis_available = Property(bool, get_axis_available, set_axis_available, reset_axis_available) only_if_joint_available = Property(bool, get_joint_available, set_joint_available, reset_joint_available) ############################## # required class boiler code # ############################## def __getitem__(self, item): return getattr(self, item) def __setitem__(self, item, value): return setattr(self, item, value)