📓
|
This is the programmer’s documentation for the official g2core-api node module: g2core-api .
|
The g2core-api
module handles all of the protocol involved in sending commands and files to a g2core device, along with handling responses and errors appropriately.
Much of the interaction with the g2core-api
module is handled by EventEmitter events. This basically means that you write g2.on('eventName', function(value) {…})
in order to handle them, and they can generally happen "at any time". (See the explanation of each event below to see when you can expect each type of event.)
The general flow of using the g2core-api
module is shown in g2core-api general code flow.
In code, the looks roughly like:
// Require "g2core-api" to get access to the G2coreAPI class
const G2coreAPI = require("g2core-api");
// Then create a G2coreAPI object called 'g2'
var g2 = new G2coreAPI();
// Setup an error handler
g2.on('error', function(error) {
// ...
});
// Open the first connected device found
g2.openFirst();
// OR: Open a specific device with one serial ports:
// g2.open(portPath);
// OR: Open a specific G2 Core device with two virtual serial ports:
// g2.open(portPath,
// {dataPortPath : dataPortPath});
// Make a status handler
var statusHandler = function(st) {
process.stdout.write(
util.inspect(status) + "\n"
);
};
// Make a close handler
var closeHandler = function() {
// Stop listening to events when closed
// This is only necessary for programs that don't exit.
g2.removeListener('statusChanged', statusHandler);
g2.removeListener('close', closeHandler);
}
// Setup an open handler, that will then setup all of the other handlers
g2.on('open', function() {
// Handle status reports ({"sr":{...}})
g2.on('statusChanged', statusHandler);
// handle 'close' events
g2.on('close', closeHandler);
// We now have an active connection to a g2core device.
// We can use g2.set(...) to set parameters on the g2core device,
// and g2.get() to read parameters (returns a promise, BTW).
// We can also use g2.sendFile() to handle sending a file.
});
The 'error'
event will pass one parameter: a object of type G2Error
, which inherits from node’s built-in Error
.
It uses the Error
class' name
and message
properties. All G2Error
objects will have a name
in the format of G2
_N_Error
. Listed below are the specific error names and what they mean, along with when they might occur.
In addition to the Error
class parameters, a G2Error
class has a data
parameter with the raw data that caused the error.
- G2ParserError
-
-
Meaning: Data coming from the g2core device was malformed
-
When: During an open connection
-
Data Contents:
-
err
is the error from the JSON parser -
part
is the raw string that was given to the parser
-
-
- G2ResponseError
-
-
Meaning: G2 reported an Error
-
When: During an open connection
-
Data Contents: The exact parsed JSON response from the g2core device.
-
- G2InAlarmError
-
-
Meaning: G2 reported an Error because the machine is in an Alarm state
-
When: During an open connection, after an Alarm was triggered. There will be several of these after a
flush()
that can be safely ignored. -
Data Contents: The exact parsed JSON response from the g2core device.
-
- G2OpenError
-
-
Meaning: g2core device failed to open a connection. This may occur if one was already open, in which case there is no change to the already-open connection, but the new one was not attempted.
-
When: Any time after
g2.open()
has been called. -
Data Contents: None.
-
- G2SerialPortError
-
-
Meaning: The underlying serialport object had an error.
-
When: Anytime after
g2.open()
was called. -
Data contents: The raw error object from serialport.
-
- G2WriteError
-
-
Meaning: The underlying serialport object reported a write error.
-
When: Anytime there’s an open connection.
-
Data Contents: The raw error from serialport.
-
- G2ReadStreamError
-
-
Meaning: The underlying readStream used by
g2.sendFile()
reported an error. -
When: After calling
g2.sendFile()
-
Data Contents: The raw error from readStream.
-
- G2OpenFirstError
-
-
Meaning:
g2.openFirst()
was unable to open a g2core device. -
When: After calling
g2.openFirst()
. -
Data Contents: The
results
value returned byg2.list()
.
-
- G2OpenFirstListError
-
-
Meaning:
g2.openFirst()
was unable to list g2core devices. -
When: After calling
g2.openFirst()
. -
Data Contents: The
err
value returned byg2.list()
.
-
-
Open a connection to a g2core device. This may use one or two serial ports.
- Returns:
-
nothing
path_or_port
-
-
string
representing the path (or port name on Windows) of the serial port of the g2core device. -
This is the control serial port when in dual-port mode (which can only happen when connected over USB), and will be opened first.
-
options
-
-
object
containing additional options:dataPortPath
-
-
A
string
representing the path (or port name) of the Data (secondary) serial port for g2core devices connected over USB.
-
-
open-example.jsconst G2coreAPI = require("g2core-api"); var g2 = new G2coreAPI(); // For a single port connection: g2.open('/dev/cu.usbmodem142411', {dataPortPath : args.dataport}); // OR, for a g2core device with two virtual ports: var list_results = { // see g2.list() for how to get this structure path: '/dev/cu.usbmodem12345', dataPortPath: '/dev/cu.usbmodem12346' } g2.open(list_results.path, {dataPortPath : list_results.dataPortPath});
-
See
g2.list()
-
Write value to the g2core device.
- Returns:
-
nothing
value
-
-
May be a
string
,object
, or array-like (according toArray.isArray(value)
). -
For strings:
-
A line-ending (
\n
) is added if one is missing -
The string it checked for single-character commands (Feedhold, Resume, etc.) or bare JSON commands (JSON Operation), and those will be sent immediately. If there are two ports, then they will be sent down the Control channel instead of the Data channel.
-
All other strings are added to the line buffer and sent in order as the g2core device is ready for them. If there are two ports, lines from the line buffer are sent down the Data channel.
write-string-example.js// Assumes g2 is a G2coreAPI object that has been opened. // Add "g0x10\n" to the line buffer, which will be sent in order as the g2core device is ready. g2.write("g0x10"); // Send "{sr:n}\n" immediately. // Note: g2.set() should be used for this purpose instead! g2.write('{sr:n}\n'); // Issue a feed hold ("pause") immediately. g2.write('!');
-
See
g2.set()
-
-
For objects that are not array-like:
-
The object is sent to
JSON.stringify(value) + '\n';
, then sent immediately.
write-object-example.js// Assumes g2 is a G2coreAPI object that has been opened. // Send '{"sr":null}\n' immediately. // Note: g2.set() should be used for this purpose instead! g2.write({sr: null});
-
See
g2.set()
-
-
For "Arrays" (objects that are array-like according to
Array.isArray(value)
):-
Each item of the array is checked for a line-ending (
\n
) and then sent directly to the line buffer. -
Do NOT send commands or JSON this way. They will not get sent ahead of moves or put in the Command channel.
-
This is intended for sending files or chunks of GCode only, and is the most efficient way to do so.
write-array-example.js// Assumes g2 is a G2coreAPI object that has been opened. // Send the following lines to the line buffer with minimal processing: var lines = "G1 F2000\nX0 Y100\nX100\nY0\nX0\nM2" g2.write(lines.split('\n'));
-
-
-
Write value to the g2core device, returning a promise to be fulfilled when the device responds.
-
The
promise.notify(response_or_sr)
function is called with the same value that is sent to thefulfilledFunction
, and can be monitored by adding aprogress()
handler on the promise. This is useful for updating of interfaces or such, but should not be used to replace thefulfilledFunction
.- Returns:
value
-
This is passed directly to
q.write()
. fulfilledFunction
-
-
(Optional.) A function that will be called with every parsed response and status report from the g2core device.
-
The function is to return
true
when that response or status report indicates that the write has completed, orfalse
if it hasn’t.
-
writeWithPromise-example.js// This function is to say the write is complete when the machine goes into stat 3 // using the 'stat' value in the status reports. // Requires 'stat' to be in your status reports. // This is almost identical to the default fulfilled function if none is provided. stat3_fulfilled_function = function (r) { // If the response is a status report, it will be in the 'sr' key: if (r && r['sr'] && r['sr']['stat'] && r['sr']['stat'] == 3) { return true; } return false; } // This function looks for line number last_line to be acknowledged (via response), // then for the machine to go to stat 3. // Requires 'stat' to be in your status reports, // and JSON Verbosity of 4. var last_line = 6; var last_line_was_seen = false; var last_stat_seen = -1; last_line_seen_fulfilled_function = function (r) { if (r && r['n'] && r['n'] == last_line) { last_line_was_seen = true; } // If the response is a status report, it will be in the 'sr' key: if (last_line_seen && r && r['sr'] && r['sr']['stat']) { last_stat_seen = r['sr']['stat']; } return ((last_stat_seen == 3) && last_line_was_seen); } // Assuming some function we_are_done() exists that we want called once // we are done (according to fulfilled_function.) // Here are the gcode lines we wish to send var lines = "N1 G1 F2000\nN2 X0 Y100\nN3 X100\nN4 Y0\nN5 X0\nN6 M2" // We will use the default fulfilled_function, which waits for stat == 3 in a // status report. g2.writeWithPromise(lines).finally(function() { we_are_done(); }); // If we wish to capture the responses and status reports (in this case we log them) // we use the progress() function of the promise. g2.writeWithPromise(lines) .finally(function() { we_are_done(); }) .progress(function(st) { console.log(util.inspect(st)); }); // We will use the last_line_seen_fulfilled_function, then call we_are_done() g2.writeWithPromise(lines, last_line_seen_fulfilled_function).then(function() { we_are_done(); });
-
Set the given value on the g2core device, returning a promise that will be finished when the last value has been set on the g2core device.
-
The
promise.notify(response)
function is called once for every parsed response object from the g2core device. These can be monitored by adding aprogress()
handler on the promise. Note that these responses are not necessarily related to the values beingset()
. No attempt at correlation is made beforenotify
is called.- Returns:
value
-
-
May be an
object
or array ofobjects
(according toArray.isArray(value)
). -
If the value is an
object
, then eachkey: value
pair will be individually sent (in effectively random order) to the g2core device (as JSON), and the response(s) will be waited for. The promise will be chained for each value to be set. -
If the value is an array of
object
values, then each element of the array will be passed toset()
and chained onto the same promise. This is effectively the same as calling set with an object, except you have control over the order that they are sent.
-
set-example.js// We will set xvm, yvm, and zvm to 3000, then start sending a file by calling some // function called "send_a_file()" (that presumably could utilize g2.sendFile()). g2.set({xvm: 3000, yvm: 3000, zvm: 3000}) .then(function() { send_a_file(); }); // Errors can be handled with the second parameter to then, or with a catch() g2.set({xvm: 3000, yvm: 3000, zvm: 3000}) .then(function() { send_a_file(); }) .catch(function(err) { all_is_lost(err); }); // If we also wish to log the responses, we could add a progress handler: g2.set({xvm: 3000, yvm: 3000, zvm: 3000}) .then(function() { send_a_file(); }) .progress(function(r) { console.log(util.inspect(r)); });
-
Retrieve the value of the given key from the g2core device, asynchronously. What;s returned is a promise, which will be fulfilled with the resulting value.
-
Note that internally
get()
callsset()
, so the response format is the same.- Returns:
key
-
The key to be retrieved as a
string
. A common example would be'sr'
to retrieve a status report.
get-example.js// We will get the value of xvm, or couldnt_get_xvm() with the error returned. g2.get("xvm") .then(function(value) { console.log("xvm value: " + xvm); }) .catch(function(err) { couldnt_get_xvm(err); });
-
Reads a file and sends it to the g2core device.
-
Use status reports to monitor the progress of the sending2.
-
Use
g2.flush()
to force the file to stop sending2.done_callback
will still be called.-
Returns::: nothing
filename_or_stdin
-
Either a path name (in a string) or a
readStream
object (such asprocess.stdin
). done_callback
-
(Optional.) A function for the g2core device object to call when the file has finished sending2. This will only be called after all lines have been sent AND
stat
has gone to 3 (movement stopped), 4 (program end viaM2
orM30
), or 6 (alarm).
⚠️ If done_callback
is not provided, then when the file is done sending the connection to the g2core device will be closed (viag2.close()
). -
-
Clears the current send buffer, cancels any active file send, and sends a job kill (^-D) and alarm clear (
{clr:n}
) to the g2core device.- Returns:
-
nothing
-
Asynchronously get a list of g2core devices available. Returns a promise.
- Returns:
-
Q promise. The promise will pass in the list of g2core device objects.
list-example.jsvar g2core device = require("g2core device"); // Then create a g2core device object called 'g' var g = new g2core device(); g2.list().then(function(results) { console.log(util.inspect(results)); }).catch(function(err) { couldnt_list(err); });
list-results.js// Results of the above should look like. [ { path: '/dev/cu.usbmodem142413', serialNumber: '021323257343', dataPortPath: '/dev/cu.usbmodem142411' } ]
-
Opens the first g2core device found, passing
options
to theopen()
call.- Returns
-
nothing
fail_if_more
-
If
true
, thenopenFirst()
will fire anerror
event and return if it finds more than one attached g2core device. options
-
These options are assed to the
open()
call. Some value may be added or modified as needed.