/ docs / src / gui / GStat.txt
GStat.txt
  1  [[cha:GStat]]
  2  
  3  = GStat
  4  
  5  == Intro
  6  
  7  GStat is a python class used to send messages from linuxcnc to other python programs. +
  8  It uses GObject to deliver messages, making it easy to listen for specific information. +
  9  This is referred to as event-driven programming, which is more efficient then every program +
 10  polling linuxcnc at the same time. +
 11  GladeVCP, Gscreen, Gmoccapy and QtVCP use GStat extensively. +
 12  GStat is in the hal_glib module
 13  
 14  == Overview
 15  
 16  First a program imports the hal_glib module and instantiates GStat. +
 17  Then it 'connects' to the messages it wishes to monitor. +
 18  GStat checks linuxcnc's status every 100ms and if there are differences from +
 19  the last check, it will send a callback message to all the connected programs +
 20  with the current status. +
 21  When GStat calls the registered function, it sends the GStat object plus any return codes from the message. +
 22  typical code signatures: +
 23  [source,python]
 24  ----
 25  GSTAT.connect('MESSGAE-TO-LISTEN-FOR', FUNCTION_TO_CALL)
 26  
 27  def FUNCTION_TO_CALL(gstat_object, return_codes):
 28  ----
 29  
 30  Often LAMBDA is used to strip the GSTAT object and manipulate the return codes): +
 31  
 32  [source,python]
 33  ----
 34  GSTAT.connect('MESSGAE-TO-LISTEN-FOR', lambda o, return: FUNCTION_TO_CALL(not return))
 35  
 36  def FUNCTION_TO_CALL(return_codes):
 37  ----
 38  
 39  == Sample GStat Code
 40  
 41  There are some basic patterns for using GStat, depending on what library +
 42  You are using them in. +
 43  If using GStat with Gladevcp, Gscreen, or Qtvcp, the gobject library is not needed, +
 44  Those toolkits already set up Gobject. +
 45  
 46  === Sample HAL component code pattern
 47  This program creates two HAL pins that output the status +
 48  of G20/G21.
 49  
 50  [source,python]
 51  ----
 52  #!/usr/bin/env python
 53  
 54  import hal
 55  from hal_glib import GStat
 56  import gobject
 57  GSTAT = GStat()
 58  
 59  # callback to change HAL pin state
 60  def mode_changed(obj, data):
 61          h['g20'] = not data
 62          h['g21'] = data
 63  
 64  # Make a component and pins
 65  h = hal.component("metric_status")
 66  h.newpin("g20", hal.HAL_BIT, hal.HAL_OUT)
 67  h.newpin("g21", hal.HAL_BIT, hal.HAL_OUT)
 68  h.ready()
 69  
 70  # connect a GSTAT message to a callback function
 71  GSTAT.connect("metric-mode-changed",mode_changed)
 72  
 73  # force GSTAT to initialize states
 74  GSTAT.forced_update()
 75  
 76  # loop till exit
 77  try:
 78          gobject.MainLoop().run()
 79  except KeyboardInterrupt:
 80      raise SystemExit
 81  ----
 82  
 83  This would be loaded with 'loadusr python PATH-TO-FILE/FILENAME.py' +
 84  or if you need to wait for the pins to be made before continuing: +
 85  'loadusr python -Wn metric_status PATH-TO-FILE/FILENAME.py' +
 86  The pins would be: 'metric_status.g20' and 'metric_status.g21' +
 87  
 88  === Sample GladeVCP python extension code pattern
 89  This file assumes there are three GTK labels named: +
 90  state_label +
 91  e_state_label +
 92  interp_state_label +
 93  
 94  [source,python]
 95  ----
 96  #!/usr/bin/env python
 97  
 98  from hal_glib import GStat
 99  GSTAT = GStat()
100  
101  class HandlerClass:
102  
103      def __init__(self, halcomp, builder, useropts):
104          self.builder = builder
105  
106          GSTAT.connect("state-estop",lambda w: self.update_estate_label('ESTOP'))
107          GSTAT.connect("state-estop-reset",lambda w: self.update_estate_label('RESET'))
108  
109          GSTAT.connect("state-on",lambda w: self.update_state_label('MACHIBE ON'))
110          GSTAT.connect("state-off",lambda w: self.update_state_label('MACHINE OFF'))
111  
112          GSTAT.connect("interp-paused",lambda w: self.update_interp_label('Paused'))
113          GSTAT.connect("interp-run",lambda w: self.update_interp_label('Run'))
114          GSTAT.connect("interp-idle",lambda w: self.update_interp_label('Idle'))
115  
116      def update_state_label(self,text):
117          self.builder.get_object('state_label').set_label("State: %s" % (text))
118  
119      def update_estate_label(self,text):
120          self.builder.get_object('e_state_label').set_label("E State: %s" % (text))
121  
122      def update_interp_label(self,text):
123          self.builder.get_object('interp_state_label').set_label("Interpeter State: %s" % (text))
124  
125  def get_handlers(halcomp,builder,useropts):
126      return [HandlerClass(halcomp,builder,useropts)]
127  ----
128  ==  Messages
129  
130  *periodic* :: '(returns nothing)' -
131  sent every 100 ms.
132  
133  *state-estop* :: '(returns nothing)' -
134  Sent when linuxcnc is goes into estop.
135  
136  *state-estop-reset*:: '(returns nothing)' -
137  Sent when linuxcnc comes out of estop.
138  
139  *state-on* :: '(returns nothing)' -
140  Sent when linuxcnc is in machine on state.
141  
142  *state-off*:: '(returns nothing)' -
143  Sent when linuxcnc is in machine off state.
144  
145  *homed* :: '(returns string)' -
146  Sent as each joint is homed.
147  
148  *all-homed* :: '(returns nothing)' -
149  Sent when all defined joints are homed.
150  
151  *not-all-homed* :: '(returns string)' -
152  Sends a list of joints not currently homed.
153  
154  *override_limits_changed* :: '(returns string)' -
155  Sent if linuxcnc has been directed to override it's limits.
156  
157  *hard-limits-tripped* :: '(returns bool, Python List)' -
158  Sent when any hard limit is tripped.
159  bool indicates if any limit is tripped, the list shows all available joint's current limit values.
160  
161  *mode-manual* :: '(returns nothing)' -
162  Sent when linuxcnc switches to manual mode.
163  
164  *mode-mdi* :: '(returns nothing)' -
165  Sent when linuxcnc switches to mdi mode.
166  
167  *mode-auto* :: '(returns nothing)' -
168  Sent when linuxcnc switches to auto mode.
169  
170  *interp-run* :: '(returns nothing)' -
171  Sent when linuxcnc's interpreter is running an MDI or program.
172  
173  *interp-idle* :: '(returns nothing)' -
174  Sent when linuxcnc's interpreter idle.
175  
176  *interp-paused* :: '(returns nothing)' -
177  Sent when linuxcnc's interpreter is paused.
178  
179  *interp-reading* :: '(returns nothing)' -
180  Sent when linuxcnc's interpreter is reading.
181  
182  *interp-waiting* :: '(returns nothing)' -
183  Sent when linuxcnc's interpreter is waiting.
184  
185  *jograte-changed* :: '(returns float)' -
186  Sent when jog rate has changed. +
187  Linuxcnc does not have an internal jog rate. +
188  This is GStat's internal jog rate. +
189  It is expected to be in the machine's native units regardless of the current unit mode .
190  
191  *jograte-angular-changed* :: '(returns float)' -
192  Sent when the angular jog rate has changed. +
193  Linuxcnc does not have an internal angular jog rate. +
194  This is GStat's internal jog rate. +
195  It is expected to be in the machine's native units regardless of the current unit mode .
196  
197  *jogincrement-changed* :: '(returns float)' -
198  Sent when jog increment has changed. +
199  Linuxcnc does not have an internal jog increment. +
200  This is GStat's internal jog increment. +
201  It is expected to be in the machine's native units regardless of the current unit mode .
202  
203  *jogincrement-angular-changed* :: '(returns float)' -
204  Sent when angular jog increment has changed. +
205  Linuxcnc does not have an internal angular jog increment. +
206  This is GStat's internal angular jog increment. +
207  It is expected to be in the machine's native units regardless of the current unit mode .
208  
209  *program-pause-changed* :: '(returns bool)' -
210  Sent when program is paused/unpaused.
211  
212  *optional-stop-changed* :: '(returns bool)' -
213  Sent when optional stop is set/unset
214  
215  *block-delete-changed* :: '(returns bool)' -
216  sent when block delete is set/unset.
217  
218  *file-loaded* :: '(returns string)' -
219  Sent when linuxcnc has loaded a file
220  
221  *reload-display* :: '(returns nothing)' -
222  Sent when there is a request to reload the display
223  
224  *line-changed* :: '(returns integer)' -
225  Sent when linuxcnc has read a new line. +
226  Linuxcnc does not update this for every type of line.
227  
228  *tool-in-spindle-changed* :: '(returns integer)' -
229  Sent when the tool has changed.
230  
231  *tool-info-changed* :: '(returns python object)' -
232  Sent when current tool info changes.
233  
234  *current-tool-offset* :: '(returns python object)' -
235  Sent when the current tool offsets change.
236  
237  *motion-mode-changed* :: '(returns integer)' -
238  Sent when motion's mode has changed
239  
240  *spindle-control-changed* :: '(returns bool, integer)' -
241  Sent when spindle direction or running status changes.
242  
243  *current-feed-rate* :: '(returns float)' -
244  Sent when the current feed rate changes.
245  
246  *current-x-rel-position* :: '(returns float)' -
247  Sent when the X relative position changes.
248  
249  *current-position* :: '(returns pyobject, pyobject, pyobject)' -
250  Sent as the current positions changes. +
251  returns tuples of position,relative position and distance-to-go.
252  
253  *current-z-rotation* :: '(returns float)' -
254  Sent as the current rotatated angle around the Z axis changes +
255  
256  *requested-spindle-speed-changed* :: '(returns float)' -
257  Sent when the current requested RPM changes
258  
259  *actual-spindle-speed-changed* :: '(returns float)' -
260  Sent when the actual RPM changes based on the HAL pin 'spindle.0.speed-in'. +
261  
262  *spindle-override-changed* :: '(returns float)' -
263  Sent when the spindle override value changes +
264  in percent
265  
266  *feed-override-changed* :: '(returns float)' -
267  Sent when the feed override value changes +
268  in percent
269  
270  *rapid-override-changed* :: '(returns float)' -
271  Sent when the rapid override value changes +
272  in percent 0-100
273  
274  *max-velocity-override-changed* :: '(returns float)' -
275  Sent when the maximum velocity override value changes +
276  in units per minute +
277  
278  *feed-hold-enabled-changed* :: '(returns bool)' -
279  Sent when feed hold status changes
280  
281  *itime-mode* :: '(returns bool)' -
282  Sent when G93 status changes +
283  (inverse time mode)
284  
285  *fpm-mode* :: '(returns bool)' -
286  Sent when G94 status changes +
287  (feed per minute mode)
288  
289  *fpr-mode* :: '(returns bool)' -
290  Sent when G95 status changes +
291  (feed per revolution mode)
292  
293  *css-mode* :: '(returns bool)' -
294  Sent when G96 status changes +
295  (constant surface feed mode)
296  
297  *rpm-mode* :: '(returns bool)' -
298  Sent when G97 status changes +
299  (constatnt RPM mode)
300  
301  *radius-mode* :: '(returns bool)' -
302  Sent when G8 status changes +
303  display X in radius mode
304  
305  *diameter-mode* :: '(returns bool)' -
306  Sent when G7 status changes +
307  display X in Diameter mode
308  
309  *flood-changed* :: '(returns bool)' -
310  Sent when flood coolant state changes.
311  
312  *mist-changed* :: '(returns bool )' -
313  Sent when mist coolant state changes.
314  
315  *m-code-changed* :: '(returns string)' -
316  Sent when active M codes change
317  
318  *g-code-changed* :: '(returns string)' -
319  Sent when active G code change
320  
321  *metric-mode-changed* :: '(returns bool)' -
322  Sent when G21 status changes
323  
324  *user-system-changed* :: '(returns string)' -
325  Sent when the reference coordinate system (G5x) changes
326  
327  *mdi-line-selected* :: '(returns string, string)' -
328  intended to be sent when an MDI line is selected by user. +
329  This depends on the widget/libraries used. +
330  
331  *gcode-line-selected* :: '(returns integer)' -
332  intended to be sent when a gcode line is selected by user. +
333  This depends on the widget/libraries used. +
334  
335  *graphics-line-selected* :: '(returns integer)' -
336  intended to be sent when graphics line is selected by user. +
337  This depends on the widget/libraries used. +
338  
339  *graphics-gcode-error* :: '(returns string)' -
340  intended to be sent when a gcode error is found when loading. +
341  This depends on the widget/libraries used. +
342  
343  *graphics-gcode-properties* :: '(returns string)' -
344  intended to be sent when gcode is loaded. +
345  This depends on the widget/libraries used. +
346  
347  *graphics-view-changed* :: '(returns string)' -
348  intended to be sent when graphics view is changed. +
349  This depends on the widget/libraries used. +
350  
351  *mdi-history-changed* :: '(returns None)' -
352  intended to be sent when an MDI history needs to be reloaded. +
353  This depends on the widget/libraries used. +
354  
355  *machine-log-changed* :: '(returns None)' -
356  intended to be sent when machine log has changed. +
357  This depends on the widget/libraries used. +
358  
359  *update-machine-log* :: '(returns string, string)' -
360  intended to be sent when updating the machine. +
361  This depends on the widget/libraries used. +
362  
363  *move-text-lineup* :: '(returns None)' -
364  intended to be sent when moving the cursor one line up in gcode display. +
365  This depends on the widget/libraries used. +
366  
367  *move-text-linedown* :: '(returns None)' -
368  intended to be sent when moving the cursor one line down in gcode display. +
369  This depends on the widget/libraries used. +
370  
371  *dialog-request* :: '(returns python dict)' -
372  intended to be sent when requesting a gui dialog. +
373  It uses a python dict for communication. +
374  The dict must include the following keyname pair: +
375  * NAME: 'requested dialog name' +
376  The dict usually has more keyname pair - it depends on the dialog. +
377  dialogs return information using a general message +
378  This depends on the widget/libraries used. +
379  
380  *focus-overlay-changed* :: '(returns bool, string, python object)' -
381  intended to be sent when requesting an overlay to be put over the display. +
382  This depends on the widget/libraries used. +
383  
384  *play-sound* :: '(returns string)' -
385  intended to be sent when requesting a specific sound file to be played. +
386  This depends on the widget/libraries used. +
387  
388  *virtual-keyboard* :: '(returns string)' -
389  intended to be sent when requesting a on screen keyboard. +
390  This depends on the widget/libraries used. +
391  
392  *dro-reference-change-request* :: '(returns integer)' -
393  intended to be sent when requesting a DRO widget to change it's reference. +
394  0 = machine, 1 = relative, 3 = distance-to-go +
395  This depends on the widget/libraries used. +
396  
397  *show-preferences* :: '(returns None)' -
398  intended to be sent when requesting the screen preferences to be displayed. +
399  This depends on the widget/libraries used. +
400  
401  *shutdown* :: '(returns None)' -
402  intended to be sent when requesting linuxcnc to shutdown. +
403  This depends on the widget/libraries used. +
404  
405  *error* :: '(returns integer, string)' -
406  intended to be sent when an error has been reported . +
407  integer represents the kind of error. ERROR, TEXT or DISPLAY +
408  string is the actual error message. +
409  This depends on the widget/libraries used. +
410  
411  *general* :: '(returns python dict)' -
412  intended to be sent when message must be sent that is not covered by a more specific message. +
413  General message should be used a sparsely as reasonable because all object connected to it will have to parse it. +
414  It uses a python dict for communication. +
415  The dict should include and be checked for a unique id  keyname pair: +
416  * ID: 'UNIQUE_ID_CODE' +
417  The dict usually has more keyname pair - it depends on implementation. +
418  
419  *forced-update* :: '(returns None)' -
420  intended to be sent when one wishes to initialize or arbitrarily update an object. +
421  This depends on the widget/libraries used. +
422  
423  == Functions
424  These are convenience functions that are commonly used in programming
425  
426  *set_jograte* :: '(float)' -
427  Linuxcnc has no internal concept of jog rate -each GUI has it's own. +
428  This is not always convenient. +
429  This function allows one to set a jog rate for all objects connected to the +
430  signal 'jograte-changed'. +
431  It defaults to 15 +
432  GSTAT.set_jog_rate(10) would set the jog rate to 10 machine-units-per-minute and emit the jograte-changed signal. +
433  
434  *get_jograte()* :: '(Nothing)' -
435  x = GSTAT.get_jograte would return GSTAT's current internal jograte.
436  
437  *set_jograte_angular* :: '(float)' -
438  
439  *get_jograte_angular* :: '(None)' -
440  
441  *set_jog_increment_angular* :: '(float, string)' -
442  
443  *get_jog_increment_angular* :: '(None)' -
444  
445  *set_jog_increments* :: '(float, string)' -
446  
447  *get_jog_increments* :: '(None)' -
448  
449  *is_all_homed* :: '(nothing)' -
450  This will return the current state of all_homed (BOOL).
451  
452  *machine_is_on* :: '(nothing)' -
453  This will return the current state of machine (BOOL).
454  
455  *estop_is_clear* :: '(nothing)' -
456  This will return the state of Estop (BOOL)
457  
458  *set_tool_touchoff* :: '(tool,axis,value)' -
459  This command will record the current mode, switch to MDI mode, +
460  invoke the MDI command: G10 L10 P[TOOL] [AXIS] [VALUE] +
461  wait for it to complete +
462  invoke G43 +
463  wait for it to complete +
464  switch back to the original mode. +
465  
466  *set_axis_origin* :: '(axis,value)' -
467  This command will record the current mode, switch to MDI mode, +
468  invoke the MDI command: G10 L20 P0 [AXIS] [VALUE] +
469  wait for it to complete +
470  switch back to the original mode. +
471  emit a 'reload-display' signal. +
472  
473  *do_jog* :: '(axis_number,direction, distance)' -
474  This will jog an axis continuously or at a set distance. +
475  You must be in the proper mode to jog.
476  
477  *check_for_modes* :: '(mode)' -
478  This function checks for required linuxcnc mode. +
479  It returns a python tuple (state, mode) +
480  mode will be set the mode the system is in +
481  state will set to: +
482  false if mode is 0 +
483  false if machine is busy +
484  true if linuxcnc is in the requested mode +
485  None if possible to change, but not in requested mode +
486  
487  *get_current_mode* :: '(nothing)' -
488  returns integer: the current linuxcnc mode. +
489  
490  *set_selected_joint* :: '(integer)' -
491  records the selected joint number internally. +
492  requests the joint to be selected by emitting the +
493  'joint-selection-changed' message. +
494  
495  *get_selected_joint* :: '(None)' -
496  returns integer representing the internal selected joint number. +
497  
498  *set_selected_axis* :: '(string)' -
499  records the selected axis letter internally. +
500  requests the axis to be selected by emitting the +
501  'axis-selection-changed' message. +
502  
503  *get_selected_axis* :: '(None)' -
504  returns string representing the internal selected axis letter. +
505  
506  *is_man_mode* :: '(None)' -
507  
508  *is_mdi_mode* :: '(None)' -
509  
510  *is_auto_mode* :: '(None)' -
511  
512  *is_on_and_idle* :: '(None)' -
513  
514  *is_auto_running* :: '(None)' -
515  
516  *is_auto_paused* :: '(None)' -
517  
518  *is_file_loaded* :: '(None)' -
519  
520  *is_metric_mode* :: '(None)' -
521  
522  *is_spindle_on* :: '(None)' -
523  
524  *shutdown* :: '(None)' -
525  
526  == Known Issues
527  
528  Some status points are reported wrongly during a running program. +
529  This is because the interpreter runs ahead of the current position of a running program. +
530  This will hopefully be resolved with the merge of state-tags branch. +
531  
532