1
0
mirror of https://github.com/bdring/Grbl_Esp32.git synced 2025-08-26 15:54:29 +02:00

Changed STATUS_ defines to enum class Error (#584)

* Changed STATUS_ defines  to enum class Error

* Added license blocks to new files

* Suppress  Compiling..Error.cpp  build script output

The filters that look for errors in the output were
triggering on the filename Error.cpp
This commit is contained in:
Mitch Bradley
2020-09-08 12:54:21 -10:00
committed by GitHub
parent 0e4013c472
commit 94b6feecce
22 changed files with 524 additions and 480 deletions

81
Grbl_Esp32/src/Error.cpp Normal file
View File

@@ -0,0 +1,81 @@
/*
Error.cpp - Error names
Part of Grbl
Copyright (c) 2014-2016 Sungeun K. Jeon for Gnea Research LLC
2018 - Bart Dring This file was modifed for use on the ESP32
CPU. Do not use this with Grbl for atMega328P
2020 - Mitch Bradley
Grbl 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 3 of the License, or
(at your option) any later version.
Grbl 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.
You should have received a copy of the GNU General Public License
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Error.h"
std::map<Error, const char*> ErrorCodes = {
{ Error::Ok, "No error" },
{ Error::ExpectedCommandLetter, "Expected GCodecommand letter" },
{ Error::BadNumberFormat, "Bad GCode number format" },
{ Error::InvalidStatement, "Invalid $ statement" },
{ Error::NegativeValue, "Negative value" },
{ Error::SettingDisabled, "Setting disabled" },
{ Error::SettingStepPulseMin, "Step pulse too short" },
{ Error::SettingReadFail, "Failed to read settings" },
{ Error::IdleError, "Command requires idle state" },
{ Error::SystemGcLock, "GCode cannot be executed in lock or alarm state" },
{ Error::SoftLimitError, "Soft limit error" },
{ Error::Overflow, "Line too long" },
{ Error::MaxStepRateExceeded, "Max step rate exceeded" },
{ Error::CheckDoor, "Check door" },
{ Error::LineLengthExceeded, "Startup line too long" },
{ Error::TravelExceeded, "Max travel exceeded during jog" },
{ Error::InvalidJogCommand, "Invalid jog command" },
{ Error::SettingDisabledLaser, "Laser mode requires PWM output" },
{ Error::GcodeUnsupportedCommand, "Unsupported GCode command" },
{ Error::GcodeModalGroupViolation, "Gcode modal group violation" },
{ Error::GcodeUndefinedFeedRate, "Gcode undefined feed rate" },
{ Error::GcodeCommandValueNotInteger, "Gcode command value not integer" },
{ Error::GcodeAxisCommandConflict, "Gcode axis command conflict" },
{ Error::GcodeWordRepeated, "Gcode word repeated" },
{ Error::GcodeNoAxisWords, "Gcode no axis words" },
{ Error::GcodeInvalidLineNumber, "Gcode invalid line number" },
{ Error::GcodeValueWordMissing, "Gcode value word missing" },
{ Error::GcodeUnsupportedCoordSys, "Gcode unsupported coordinate system" },
{ Error::GcodeG53InvalidMotionMode, "Gcode G53 invalid motion mode" },
{ Error::GcodeAxisWordsExist, "Gcode extra axis words" },
{ Error::GcodeNoAxisWordsInPlane, "Gcode no axis words in plane" },
{ Error::GcodeInvalidTarget, "Gcode invalid target" },
{ Error::GcodeArcRadiusError, "Gcode arc radius error" },
{ Error::GcodeNoOffsetsInPlane, "Gcode no offsets in plane" },
{ Error::GcodeUnusedWords, "Gcode unused words" },
{ Error::GcodeG43DynamicAxisError, "Gcode G43 dynamic axis error" },
{ Error::GcodeMaxValueExceeded, "Gcode max value exceeded" },
{ Error::PParamMaxExceeded, "P param max exceeded" },
{ Error::SdFailedMount, "SD failed mount" },
{ Error::SdFailedRead, "SD failed read" },
{ Error::SdFailedOpenDir, "SD failed to open directory" },
{ Error::SdDirNotFound, "SD directory not found" },
{ Error::SdFileEmpty, "SD file empty" },
{ Error::SdFileNotFound, "SD file not found" },
{ Error::SdFailedOpenFile, "SD failed to open file" },
{ Error::SdFailedBusy, "SD is busy" },
{ Error::SdFailedDelDir, "SD failed to delete directory" },
{ Error::SdFailedDelFile, "SD failed to delete file" },
{ Error::BtFailBegin, "Bluetooth failed to start" },
{ Error::WifiFailBegin, "WiFi failed to start" },
{ Error::NumberRange, "Number out of range for setting" },
{ Error::InvalidValue, "Invalid value for setting" },
{ Error::MessageFailed, "Failed to send message" },
{ Error::NvsSetFailed, "Failed to store setting" },
{ Error::NvsGetStatsFailed, "Failed to get setting status" },
{ Error::AuthenticationFailed, "Authentication failed!" },
};

87
Grbl_Esp32/src/Error.h Normal file
View File

@@ -0,0 +1,87 @@
#pragma once
/*
Error.h - Error numbers
Part of Grbl
Copyright (c) 2014-2016 Sungeun K. Jeon for Gnea Research LLC
2018 - Bart Dring This file was modifed for use on the ESP32
CPU. Do not use this with Grbl for atMega328P
2020 - Mitch Bradley
Grbl 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 3 of the License, or
(at your option) any later version.
Grbl 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.
You should have received a copy of the GNU General Public License
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
*/
#include <map>
// Grbl error codes. Valid values (0-255)
enum class Error : uint8_t {
Ok = 0,
ExpectedCommandLetter = 1,
BadNumberFormat = 2,
InvalidStatement = 3,
NegativeValue = 4,
SettingDisabled = 5,
SettingStepPulseMin = 6,
SettingReadFail = 7,
IdleError = 8,
SystemGcLock = 9,
SoftLimitError = 10,
Overflow = 11,
MaxStepRateExceeded = 12,
CheckDoor = 13,
LineLengthExceeded = 14,
TravelExceeded = 15,
InvalidJogCommand = 16,
SettingDisabledLaser = 17,
GcodeUnsupportedCommand = 20,
GcodeModalGroupViolation = 21,
GcodeUndefinedFeedRate = 22,
GcodeCommandValueNotInteger = 23,
GcodeAxisCommandConflict = 24,
GcodeWordRepeated = 25,
GcodeNoAxisWords = 26,
GcodeInvalidLineNumber = 27,
GcodeValueWordMissing = 28,
GcodeUnsupportedCoordSys = 29,
GcodeG53InvalidMotionMode = 30,
GcodeAxisWordsExist = 31,
GcodeNoAxisWordsInPlane = 32,
GcodeInvalidTarget = 33,
GcodeArcRadiusError = 34,
GcodeNoOffsetsInPlane = 35,
GcodeUnusedWords = 36,
GcodeG43DynamicAxisError = 37,
GcodeMaxValueExceeded = 38,
PParamMaxExceeded = 39,
SdFailedMount = 60, // SD Failed to mount
SdFailedRead = 61, // SD Failed to read file
SdFailedOpenDir = 62, // SD card failed to open directory
SdDirNotFound = 63, // SD Card directory not found
SdFileEmpty = 64, // SD Card directory not found
SdFileNotFound = 65, // SD Card file not found
SdFailedOpenFile = 66, // SD card failed to open file
SdFailedBusy = 67, // SD card is busy
SdFailedDelDir = 68,
SdFailedDelFile = 69,
BtFailBegin = 70, // Bluetooth failed to start
WifiFailBegin = 71, // WiFi failed to start
NumberRange = 80, // Setting number range problem
InvalidValue = 81, // Setting string problem
MessageFailed = 90,
NvsSetFailed = 100,
NvsGetStatsFailed = 101,
AuthenticationFailed = 110,
Eol = 111,
};
extern std::map<Error, const char*> ErrorCodes;

View File

@@ -40,7 +40,7 @@ void gc_init() {
memset(&gc_state, 0, sizeof(parser_state_t)); memset(&gc_state, 0, sizeof(parser_state_t));
// Load default G54 coordinate system. // Load default G54 coordinate system.
if (!(settings_read_coord_data(gc_state.modal.coord_select, gc_state.coord_system))) { if (!(settings_read_coord_data(gc_state.modal.coord_select, gc_state.coord_system))) {
report_status_message(STATUS_SETTING_READ_FAIL, CLIENT_SERIAL); report_status_message(Error::SettingReadFail, CLIENT_SERIAL);
} }
} }
@@ -115,7 +115,7 @@ void collapseGCode(char* line) {
// In this function, all units and positions are converted and // In this function, all units and positions are converted and
// exported to grbl's internal functions in terms of (mm, mm/min) and absolute machine // exported to grbl's internal functions in terms of (mm, mm/min) and absolute machine
// coordinates, respectively. // coordinates, respectively.
uint8_t gc_execute_line(char* line, uint8_t client) { Error gc_execute_line(char* line, uint8_t client) {
// Step 0 - remove whitespace and comments and convert to upper case // Step 0 - remove whitespace and comments and convert to upper case
collapseGCode(line); collapseGCode(line);
#ifdef REPORT_ECHO_LINE_RECEIVED #ifdef REPORT_ECHO_LINE_RECEIVED
@@ -171,11 +171,11 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
// Import the next g-code word, expecting a letter followed by a value. Otherwise, error out. // Import the next g-code word, expecting a letter followed by a value. Otherwise, error out.
letter = line[char_counter]; letter = line[char_counter];
if ((letter < 'A') || (letter > 'Z')) { if ((letter < 'A') || (letter > 'Z')) {
FAIL(STATUS_EXPECTED_COMMAND_LETTER); // [Expected word letter] FAIL(Error::ExpectedCommandLetter); // [Expected word letter]
} }
char_counter++; char_counter++;
if (!read_float(line, &char_counter, &value)) { if (!read_float(line, &char_counter, &value)) {
FAIL(STATUS_BAD_NUMBER_FORMAT); // [Expected word value] FAIL(Error::BadNumberFormat); // [Expected word value]
} }
// Convert values to smaller uint8 significand and mantissa values for parsing this word. // Convert values to smaller uint8 significand and mantissa values for parsing this word.
// NOTE: Mantissa is multiplied by 100 to catch non-integer command values. This is more // NOTE: Mantissa is multiplied by 100 to catch non-integer command values. This is more
@@ -200,7 +200,7 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
gc_block.non_modal_command = NonModal::SetCoordinateData; gc_block.non_modal_command = NonModal::SetCoordinateData;
if (mantissa == 0) { if (mantissa == 0) {
if (axis_command != AxisCommand::None) { if (axis_command != AxisCommand::None) {
FAIL(STATUS_GCODE_AXIS_COMMAND_CONFLICT); // [Axis word/command conflict] FAIL(Error::GcodeAxisCommandConflict); // [Axis word/command conflict]
} }
axis_command = AxisCommand::NonModal; axis_command = AxisCommand::NonModal;
} }
@@ -217,7 +217,7 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
switch (mantissa) { switch (mantissa) {
case 0: // Ignore G28.1, G30.1, and G92.1 case 0: // Ignore G28.1, G30.1, and G92.1
if (axis_command != AxisCommand::None) { if (axis_command != AxisCommand::None) {
FAIL(STATUS_GCODE_AXIS_COMMAND_CONFLICT); // [Axis word/command conflict] FAIL(Error::GcodeAxisCommandConflict); // [Axis word/command conflict]
} }
axis_command = AxisCommand::NonModal; axis_command = AxisCommand::NonModal;
break; break;
@@ -225,7 +225,7 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
mantissa = 0; // Set to zero to indicate valid non-integer G command. mantissa = 0; // Set to zero to indicate valid non-integer G command.
break; break;
default: default:
FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); FAIL(Error::GcodeUnsupportedCommand);
// not reached // not reached
break; break;
} }
@@ -264,12 +264,12 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
case 38: // G38 - probe case 38: // G38 - probe
#ifndef PROBE_PIN //only allow G38 "Probe" commands if a probe pin is defined. #ifndef PROBE_PIN //only allow G38 "Probe" commands if a probe pin is defined.
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "No probe pin defined"); grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "No probe pin defined");
FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); // [Unsupported G command] FAIL(Error::GcodeUnsupportedCommand); // [Unsupported G command]
#endif #endif
// Check for G0/1/2/3/38 being called with G10/28/30/92 on same block. // Check for G0/1/2/3/38 being called with G10/28/30/92 on same block.
// * G43.1 is also an axis command but is not explicitly defined this way. // * G43.1 is also an axis command but is not explicitly defined this way.
if (axis_command != AxisCommand::None) { if (axis_command != AxisCommand::None) {
FAIL(STATUS_GCODE_AXIS_COMMAND_CONFLICT); // [Axis word/command conflict] FAIL(Error::GcodeAxisCommandConflict); // [Axis word/command conflict]
} }
axis_command = AxisCommand::MotionMode; axis_command = AxisCommand::MotionMode;
switch (mantissa) { switch (mantissa) {
@@ -277,7 +277,7 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
case 30: gc_block.modal.motion = Motion::ProbeTowardNoError; break; case 30: gc_block.modal.motion = Motion::ProbeTowardNoError; break;
case 40: gc_block.modal.motion = Motion::ProbeAway; break; case 40: gc_block.modal.motion = Motion::ProbeAway; break;
case 50: gc_block.modal.motion = Motion::ProbeAway; break; case 50: gc_block.modal.motion = Motion::ProbeAway; break;
default: FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); break; // [Unsupported G38.x command] default: FAIL(Error::GcodeUnsupportedCommand); break; // [Unsupported G38.x command]
} }
mantissa = 0; // Set to zero to indicate valid non-integer G command. mantissa = 0; // Set to zero to indicate valid non-integer G command.
mg_word_bit = ModalGroup::MG1; mg_word_bit = ModalGroup::MG1;
@@ -306,11 +306,11 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
mg_word_bit = ModalGroup::MG3; mg_word_bit = ModalGroup::MG3;
break; break;
case 10: case 10:
FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); // [G90.1 not supported] FAIL(Error::GcodeUnsupportedCommand); // [G90.1 not supported]
// mg_word_bit = ModalGroup::MG4; // mg_word_bit = ModalGroup::MG4;
// gc_block.modal.distance_arc = ArcDistance::Absolute; // gc_block.modal.distance_arc = ArcDistance::Absolute;
break; break;
default: FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); break; default: FAIL(Error::GcodeUnsupportedCommand); break;
} }
break; break;
case 91: case 91:
@@ -325,7 +325,7 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
// gc_block.modal.distance_arc = ArcDistance::Incremental; // gc_block.modal.distance_arc = ArcDistance::Incremental;
mg_word_bit = ModalGroup::MG4; mg_word_bit = ModalGroup::MG4;
break; break;
default: FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); break; default: FAIL(Error::GcodeUnsupportedCommand); break;
} }
break; break;
case 93: case 93:
@@ -356,7 +356,7 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
// there cannot be any axis motion or coordinate offsets updated. Meaning G43, G43.1, and G49 // there cannot be any axis motion or coordinate offsets updated. Meaning G43, G43.1, and G49
// all are explicit axis commands, regardless if they require axis words or not. // all are explicit axis commands, regardless if they require axis words or not.
if (axis_command != AxisCommand::None) { if (axis_command != AxisCommand::None) {
FAIL(STATUS_GCODE_AXIS_COMMAND_CONFLICT); FAIL(Error::GcodeAxisCommandConflict);
} }
// [Axis word/command conflict] } // [Axis word/command conflict] }
axis_command = AxisCommand::ToolLengthOffset; axis_command = AxisCommand::ToolLengthOffset;
@@ -365,7 +365,7 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
} else if (mantissa == 10) { // G43.1 } else if (mantissa == 10) { // G43.1
gc_block.modal.tool_length = ToolLengthOffset::EnableDynamic; gc_block.modal.tool_length = ToolLengthOffset::EnableDynamic;
} else { } else {
FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); // [Unsupported G43.x command] FAIL(Error::GcodeUnsupportedCommand); // [Unsupported G43.x command]
} }
mantissa = 0; // Set to zero to indicate valid non-integer G command. mantissa = 0; // Set to zero to indicate valid non-integer G command.
mg_word_bit = ModalGroup::MG8; mg_word_bit = ModalGroup::MG8;
@@ -382,28 +382,28 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
break; break;
case 61: case 61:
if (mantissa != 0) { if (mantissa != 0) {
FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); // [G61.1 not supported] FAIL(Error::GcodeUnsupportedCommand); // [G61.1 not supported]
} }
// gc_block.modal.control = ControlMode::ExactPath; // G61 // gc_block.modal.control = ControlMode::ExactPath; // G61
mg_word_bit = ModalGroup::MG13; mg_word_bit = ModalGroup::MG13;
break; break;
default: FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); // [Unsupported G command] default: FAIL(Error::GcodeUnsupportedCommand); // [Unsupported G command]
} }
if (mantissa > 0) { if (mantissa > 0) {
FAIL(STATUS_GCODE_COMMAND_VALUE_NOT_INTEGER); // [Unsupported or invalid Gxx.x command] FAIL(Error::GcodeCommandValueNotInteger); // [Unsupported or invalid Gxx.x command]
} }
// Check for more than one command per modal group violations in the current block // Check for more than one command per modal group violations in the current block
// NOTE: Variable 'mg_word_bit' is always assigned, if the command is valid. // NOTE: Variable 'mg_word_bit' is always assigned, if the command is valid.
bitmask = bit(mg_word_bit); bitmask = bit(mg_word_bit);
if (bit_istrue(command_words, bitmask)) { if (bit_istrue(command_words, bitmask)) {
FAIL(STATUS_GCODE_MODAL_GROUP_VIOLATION); FAIL(Error::GcodeModalGroupViolation);
} }
command_words |= bitmask; command_words |= bitmask;
break; break;
case 'M': case 'M':
// Determine 'M' command and its modal group // Determine 'M' command and its modal group
if (mantissa > 0) { if (mantissa > 0) {
FAIL(STATUS_GCODE_COMMAND_VALUE_NOT_INTEGER); // [No Mxx.x commands] FAIL(Error::GcodeCommandValueNotInteger); // [No Mxx.x commands]
} }
switch (int_value) { switch (int_value) {
case 0: case 0:
@@ -434,7 +434,7 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
if (spindle->is_reversable || laser_mode->get()) { if (spindle->is_reversable || laser_mode->get()) {
gc_block.modal.spindle = SpindleState::Ccw; gc_block.modal.spindle = SpindleState::Ccw;
} else { } else {
FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); FAIL(Error::GcodeUnsupportedCommand);
} }
break; break;
case 5: gc_block.modal.spindle = SpindleState::Disable; break; case 5: gc_block.modal.spindle = SpindleState::Disable; break;
@@ -453,18 +453,12 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
case 9: case 9:
switch (int_value) { switch (int_value) {
#ifdef COOLANT_MIST_PIN #ifdef COOLANT_MIST_PIN
case 7: case 7: gc_block.coolant = GCodeCoolant::M7; break;
gc_block.coolant = GCodeCoolant::M7;
break;
#endif #endif
#ifdef COOLANT_FLOOD_PIN #ifdef COOLANT_FLOOD_PIN
case 8: case 8: gc_block.coolant = GCodeCoolant::M8; break;
gc_block.coolant = GCodeCoolant::M8;
break;
#endif #endif
case 9: case 9: gc_block.coolant = GCodeCoolant::M9; break;
gc_block.coolant = GCodeCoolant::M9;
break;
} }
mg_word_bit = ModalGroup::MM8; mg_word_bit = ModalGroup::MM8;
break; break;
@@ -482,13 +476,13 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
gc_block.modal.io_control = IoControl::Disable; gc_block.modal.io_control = IoControl::Disable;
mg_word_bit = ModalGroup::MM10; mg_word_bit = ModalGroup::MM10;
break; break;
default: FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); // [Unsupported M command] default: FAIL(Error::GcodeUnsupportedCommand); // [Unsupported M command]
} }
// Check for more than one command per modal group violations in the current block // Check for more than one command per modal group violations in the current block
// NOTE: Variable 'mg_word_bit' is always assigned, if the command is valid. // NOTE: Variable 'mg_word_bit' is always assigned, if the command is valid.
bitmask = bit(mg_word_bit); bitmask = bit(mg_word_bit);
if (bit_istrue(command_words, bitmask)) { if (bit_istrue(command_words, bitmask)) {
FAIL(STATUS_GCODE_MODAL_GROUP_VIOLATION); FAIL(Error::GcodeModalGroupViolation);
} }
command_words |= bitmask; command_words |= bitmask;
break; break;
@@ -566,7 +560,7 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
case 'T': case 'T':
axis_word_bit = GCodeWord::T; axis_word_bit = GCodeWord::T;
if (value > MaxToolNumber) { if (value > MaxToolNumber) {
FAIL(STATUS_GCODE_MAX_VALUE_EXCEEDED); FAIL(Error::GcodeMaxValueExceeded);
} }
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Tool No: %d", int_value); grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Tool No: %d", int_value);
gc_state.tool = int_value; gc_state.tool = int_value;
@@ -586,18 +580,18 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
gc_block.values.xyz[Z_AXIS] = value; gc_block.values.xyz[Z_AXIS] = value;
axis_words |= bit(Z_AXIS); axis_words |= bit(Z_AXIS);
break; break;
default: FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); default: FAIL(Error::GcodeUnsupportedCommand);
} }
// NOTE: Variable 'axis_word_bit' is always assigned, if the non-command letter is valid. // NOTE: Variable 'axis_word_bit' is always assigned, if the non-command letter is valid.
bitmask = bit(axis_word_bit); bitmask = bit(axis_word_bit);
if (bit_istrue(value_words, bitmask)) { if (bit_istrue(value_words, bitmask)) {
FAIL(STATUS_GCODE_WORD_REPEATED); // [Word repeated] FAIL(Error::GcodeWordRepeated); // [Word repeated]
} }
// Check for invalid negative values for words F, N, P, T, and S. // Check for invalid negative values for words F, N, P, T, and S.
// NOTE: Negative value check is done here simply for code-efficiency. // NOTE: Negative value check is done here simply for code-efficiency.
if (bitmask & (bit(GCodeWord::F) | bit(GCodeWord::N) | bit(GCodeWord::P) | bit(GCodeWord::T) | bit(GCodeWord::S))) { if (bitmask & (bit(GCodeWord::F) | bit(GCodeWord::N) | bit(GCodeWord::P) | bit(GCodeWord::T) | bit(GCodeWord::S))) {
if (value < 0.0) { if (value < 0.0) {
FAIL(STATUS_NEGATIVE_VALUE); // [Word value cannot be negative] FAIL(Error::NegativeValue); // [Word value cannot be negative]
} }
} }
value_words |= bitmask; // Flag to indicate parameter assigned. value_words |= bitmask; // Flag to indicate parameter assigned.
@@ -640,7 +634,7 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
if (bit_istrue(value_words, bit(GCodeWord::N))) { if (bit_istrue(value_words, bit(GCodeWord::N))) {
// Line number value cannot be less than zero (done) or greater than max line number. // Line number value cannot be less than zero (done) or greater than max line number.
if (gc_block.values.n > MaxLineNumber) { if (gc_block.values.n > MaxLineNumber) {
FAIL(STATUS_GCODE_INVALID_LINE_NUMBER); // [Exceeds max line number] FAIL(Error::GcodeInvalidLineNumber); // [Exceeds max line number]
} }
} }
// bit_false(value_words,bit(GCodeWord::N)); // NOTE: Single-meaning value word. Set at end of error-checking. // bit_false(value_words,bit(GCodeWord::N)); // NOTE: Single-meaning value word. Set at end of error-checking.
@@ -656,7 +650,7 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
// NOTE: For jogging, ignore prior feed rate mode. Enforce G94 and check for required F word. // NOTE: For jogging, ignore prior feed rate mode. Enforce G94 and check for required F word.
if (gc_parser_flags & GCParserJogMotion) { if (gc_parser_flags & GCParserJogMotion) {
if (bit_isfalse(value_words, bit(GCodeWord::F))) { if (bit_isfalse(value_words, bit(GCodeWord::F))) {
FAIL(STATUS_GCODE_UNDEFINED_FEED_RATE); FAIL(Error::GcodeUndefinedFeedRate);
} }
if (gc_block.modal.units == Units::Inches) { if (gc_block.modal.units == Units::Inches) {
gc_block.values.f *= MM_PER_INCH; gc_block.values.f *= MM_PER_INCH;
@@ -667,7 +661,7 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
if (axis_command == AxisCommand::MotionMode) { if (axis_command == AxisCommand::MotionMode) {
if ((gc_block.modal.motion != Motion::None) || (gc_block.modal.motion != Motion::Seek)) { if ((gc_block.modal.motion != Motion::None) || (gc_block.modal.motion != Motion::Seek)) {
if (bit_isfalse(value_words, bit(GCodeWord::F))) { if (bit_isfalse(value_words, bit(GCodeWord::F))) {
FAIL(STATUS_GCODE_UNDEFINED_FEED_RATE); // [F word missing] FAIL(Error::GcodeUndefinedFeedRate); // [F word missing]
} }
} }
} }
@@ -720,13 +714,13 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
// [10. Dwell ]: P value missing. P is negative (done.) NOTE: See below. // [10. Dwell ]: P value missing. P is negative (done.) NOTE: See below.
if (gc_block.non_modal_command == NonModal::Dwell) { if (gc_block.non_modal_command == NonModal::Dwell) {
if (bit_isfalse(value_words, bit(GCodeWord::P))) { if (bit_isfalse(value_words, bit(GCodeWord::P))) {
FAIL(STATUS_GCODE_VALUE_WORD_MISSING); // [P word missing] FAIL(Error::GcodeValueWordMissing); // [P word missing]
} }
bit_false(value_words, bit(GCodeWord::P)); bit_false(value_words, bit(GCodeWord::P));
} }
if ((gc_block.modal.io_control == IoControl::Enable) || (gc_block.modal.io_control == IoControl::Disable)) { if ((gc_block.modal.io_control == IoControl::Enable) || (gc_block.modal.io_control == IoControl::Disable)) {
if (bit_isfalse(value_words, bit(GCodeWord::P))) { if (bit_isfalse(value_words, bit(GCodeWord::P))) {
FAIL(STATUS_GCODE_VALUE_WORD_MISSING); // [P word missing] FAIL(Error::GcodeValueWordMissing); // [P word missing]
} }
bit_false(value_words, bit(GCodeWord::P)); bit_false(value_words, bit(GCodeWord::P));
} }
@@ -769,7 +763,7 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
if (axis_command == AxisCommand::ToolLengthOffset) { // Indicates called in block. if (axis_command == AxisCommand::ToolLengthOffset) { // Indicates called in block.
if (gc_block.modal.tool_length == ToolLengthOffset::EnableDynamic) { if (gc_block.modal.tool_length == ToolLengthOffset::EnableDynamic) {
if (axis_words ^ bit(TOOL_LENGTH_OFFSET_AXIS)) { if (axis_words ^ bit(TOOL_LENGTH_OFFSET_AXIS)) {
FAIL(STATUS_GCODE_G43_DYNAMIC_AXIS_ERROR); FAIL(Error::GcodeG43DynamicAxisError);
} }
} }
} }
@@ -782,11 +776,11 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
memcpy(block_coord_system, gc_state.coord_system, sizeof(gc_state.coord_system)); memcpy(block_coord_system, gc_state.coord_system, sizeof(gc_state.coord_system));
if (bit_istrue(command_words, bit(ModalGroup::MG12))) { // Check if called in block if (bit_istrue(command_words, bit(ModalGroup::MG12))) { // Check if called in block
if (gc_block.modal.coord_select > N_COORDINATE_SYSTEM) { if (gc_block.modal.coord_select > N_COORDINATE_SYSTEM) {
FAIL(STATUS_GCODE_UNSUPPORTED_COORD_SYS); // [Greater than N sys] FAIL(Error::GcodeUnsupportedCoordSys); // [Greater than N sys]
} }
if (gc_state.modal.coord_select != gc_block.modal.coord_select) { if (gc_state.modal.coord_select != gc_block.modal.coord_select) {
if (!(settings_read_coord_data(gc_block.modal.coord_select, block_coord_system))) { if (!(settings_read_coord_data(gc_block.modal.coord_select, block_coord_system))) {
FAIL(STATUS_SETTING_READ_FAIL); FAIL(Error::SettingReadFail);
} }
} }
} }
@@ -804,22 +798,22 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
// [G10 L2 Errors]: R word NOT SUPPORTED. P value not 0 to nCoordSys(max 9). Axis words missing. // [G10 L2 Errors]: R word NOT SUPPORTED. P value not 0 to nCoordSys(max 9). Axis words missing.
// [G10 L20 Errors]: P must be 0 to nCoordSys(max 9). Axis words missing. // [G10 L20 Errors]: P must be 0 to nCoordSys(max 9). Axis words missing.
if (!axis_words) { if (!axis_words) {
FAIL(STATUS_GCODE_NO_AXIS_WORDS) FAIL(Error::GcodeNoAxisWords)
}; // [No axis words] }; // [No axis words]
if (bit_isfalse(value_words, (bit(GCodeWord::P) | bit(GCodeWord::L)))) { if (bit_isfalse(value_words, (bit(GCodeWord::P) | bit(GCodeWord::L)))) {
FAIL(STATUS_GCODE_VALUE_WORD_MISSING); // [P/L word missing] FAIL(Error::GcodeValueWordMissing); // [P/L word missing]
} }
coord_select = trunc(gc_block.values.p); // Convert p value to int. coord_select = trunc(gc_block.values.p); // Convert p value to int.
if (coord_select > N_COORDINATE_SYSTEM) { if (coord_select > N_COORDINATE_SYSTEM) {
FAIL(STATUS_GCODE_UNSUPPORTED_COORD_SYS); // [Greater than N sys] FAIL(Error::GcodeUnsupportedCoordSys); // [Greater than N sys]
} }
if (gc_block.values.l != 20) { if (gc_block.values.l != 20) {
if (gc_block.values.l == 2) { if (gc_block.values.l == 2) {
if (bit_istrue(value_words, bit(GCodeWord::R))) { if (bit_istrue(value_words, bit(GCodeWord::R))) {
FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); // [G10 L2 R not supported] FAIL(Error::GcodeUnsupportedCommand); // [G10 L2 R not supported]
} }
} else { } else {
FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); // [Unsupported L] FAIL(Error::GcodeUnsupportedCommand); // [Unsupported L]
} }
} }
bit_false(value_words, (bit(GCodeWord::L) | bit(GCodeWord::P))); bit_false(value_words, (bit(GCodeWord::L) | bit(GCodeWord::P)));
@@ -832,7 +826,7 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
// NOTE: Store parameter data in IJK values. By rule, they are not in use with this command. // NOTE: Store parameter data in IJK values. By rule, they are not in use with this command.
// FIXME: Instead of IJK, we'd better use: float vector[N_AXIS]; // [DG] // FIXME: Instead of IJK, we'd better use: float vector[N_AXIS]; // [DG]
if (!settings_read_coord_data(coord_select, gc_block.values.ijk)) { if (!settings_read_coord_data(coord_select, gc_block.values.ijk)) {
FAIL(STATUS_SETTING_READ_FAIL); // [EEPROM read fail] FAIL(Error::SettingReadFail); // [EEPROM read fail]
} }
// Pre-calculate the coordinate data changes. // Pre-calculate the coordinate data changes.
for (idx = 0; idx < N_AXIS; idx++) { // Axes indices are consistent, so loop may be used. for (idx = 0; idx < N_AXIS; idx++) { // Axes indices are consistent, so loop may be used.
@@ -855,7 +849,7 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
case NonModal::SetCoordinateOffset: case NonModal::SetCoordinateOffset:
// [G92 Errors]: No axis words. // [G92 Errors]: No axis words.
if (!axis_words) { if (!axis_words) {
FAIL(STATUS_GCODE_NO_AXIS_WORDS); // [No axis words] FAIL(Error::GcodeNoAxisWords); // [No axis words]
} }
// Update axes defined only in block. Offsets current system to defined value. Does not update when // Update axes defined only in block. Offsets current system to defined value. Does not update when
// active coordinate system is selected, but is still active unless G92.1 disables it. // active coordinate system is selected, but is still active unless G92.1 disables it.
@@ -908,11 +902,11 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
// NOTE: Store parameter data in IJK values. By rule, they are not in use with this command. // NOTE: Store parameter data in IJK values. By rule, they are not in use with this command.
if (gc_block.non_modal_command == NonModal::GoHome0) { if (gc_block.non_modal_command == NonModal::GoHome0) {
if (!settings_read_coord_data(SETTING_INDEX_G28, gc_block.values.ijk)) { if (!settings_read_coord_data(SETTING_INDEX_G28, gc_block.values.ijk)) {
FAIL(STATUS_SETTING_READ_FAIL); FAIL(Error::SettingReadFail);
} }
} else { // == NonModal::GoHome1 } else { // == NonModal::GoHome1
if (!settings_read_coord_data(SETTING_INDEX_G30, gc_block.values.ijk)) { if (!settings_read_coord_data(SETTING_INDEX_G30, gc_block.values.ijk)) {
FAIL(STATUS_SETTING_READ_FAIL); FAIL(Error::SettingReadFail);
} }
} }
if (axis_words) { if (axis_words) {
@@ -938,7 +932,7 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
// [G53 Errors]: G0 and G1 are not active. Cutter compensation is enabled. // [G53 Errors]: G0 and G1 are not active. Cutter compensation is enabled.
// NOTE: All explicit axis word commands are in this modal group. So no implicit check necessary. // NOTE: All explicit axis word commands are in this modal group. So no implicit check necessary.
if (!(gc_block.modal.motion == Motion::Seek || gc_block.modal.motion == Motion::Linear)) { if (!(gc_block.modal.motion == Motion::Seek || gc_block.modal.motion == Motion::Linear)) {
FAIL(STATUS_GCODE_G53_INVALID_MOTION_MODE); // [G53 G0/1 not active] FAIL(Error::GcodeG53InvalidMotionMode); // [G53 G0/1 not active]
} }
break; break;
default: break; default: break;
@@ -949,7 +943,7 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
// [G80 Errors]: Axis word are programmed while G80 is active. // [G80 Errors]: Axis word are programmed while G80 is active.
// NOTE: Even non-modal commands or TLO that use axis words will throw this strict error. // NOTE: Even non-modal commands or TLO that use axis words will throw this strict error.
if (axis_words) { if (axis_words) {
FAIL(STATUS_GCODE_AXIS_WORDS_EXIST); // [No axis words allowed] FAIL(Error::GcodeAxisWordsExist); // [No axis words allowed]
} }
// Check remaining motion modes, if axis word are implicit (exist and not used by G10/28/30/92), or // Check remaining motion modes, if axis word are implicit (exist and not used by G10/28/30/92), or
// was explicitly commanded in the g-code block. // was explicitly commanded in the g-code block.
@@ -965,7 +959,7 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
} else { } else {
// Check if feed rate is defined for the motion modes that require it. // Check if feed rate is defined for the motion modes that require it.
if (gc_block.values.f == 0.0) { if (gc_block.values.f == 0.0) {
FAIL(STATUS_GCODE_UNDEFINED_FEED_RATE); // [Feed rate undefined] FAIL(Error::GcodeUndefinedFeedRate); // [Feed rate undefined]
} }
switch (gc_block.modal.motion) { switch (gc_block.modal.motion) {
case Motion::None: break; // Feed rate is unnecessary case Motion::None: break; // Feed rate is unnecessary
@@ -986,10 +980,10 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
// [G2/3 Full-Circle-Mode Errors]: NOT SUPPORTED. Axis words exist. No offsets programmed. P must be an integer. // [G2/3 Full-Circle-Mode Errors]: NOT SUPPORTED. Axis words exist. No offsets programmed. P must be an integer.
// NOTE: Both radius and offsets are required for arc tracing and are pre-computed with the error-checking. // NOTE: Both radius and offsets are required for arc tracing and are pre-computed with the error-checking.
if (!axis_words) { if (!axis_words) {
FAIL(STATUS_GCODE_NO_AXIS_WORDS); // [No axis words] FAIL(Error::GcodeNoAxisWords); // [No axis words]
} }
if (!(axis_words & (bit(axis_0) | bit(axis_1)))) { if (!(axis_words & (bit(axis_0) | bit(axis_1)))) {
FAIL(STATUS_GCODE_NO_AXIS_WORDS_IN_PLANE); // [No axis words in plane] FAIL(Error::GcodeNoAxisWordsInPlane); // [No axis words in plane]
} }
// Calculate the change in position along each selected axis // Calculate the change in position along each selected axis
float x, y; float x, y;
@@ -998,7 +992,7 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
if (value_words & bit(GCodeWord::R)) { // Arc Radius Mode if (value_words & bit(GCodeWord::R)) { // Arc Radius Mode
bit_false(value_words, bit(GCodeWord::R)); bit_false(value_words, bit(GCodeWord::R));
if (isequal_position_vector(gc_state.position, gc_block.values.xyz)) { if (isequal_position_vector(gc_state.position, gc_block.values.xyz)) {
FAIL(STATUS_GCODE_INVALID_TARGET); // [Invalid target] FAIL(Error::GcodeInvalidTarget); // [Invalid target]
} }
// Convert radius value to proper units. // Convert radius value to proper units.
if (gc_block.modal.units == Units::Inches) { if (gc_block.modal.units == Units::Inches) {
@@ -1055,7 +1049,7 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
// than d. If so, the sqrt of a negative number is complex and error out. // than d. If so, the sqrt of a negative number is complex and error out.
float h_x2_div_d = 4.0 * gc_block.values.r * gc_block.values.r - x * x - y * y; float h_x2_div_d = 4.0 * gc_block.values.r * gc_block.values.r - x * x - y * y;
if (h_x2_div_d < 0) { if (h_x2_div_d < 0) {
FAIL(STATUS_GCODE_ARC_RADIUS_ERROR); // [Arc radius error] FAIL(Error::GcodeArcRadiusError); // [Arc radius error]
} }
// Finish computing h_x2_div_d. // Finish computing h_x2_div_d.
h_x2_div_d = -sqrt(h_x2_div_d) / hypot_f(x, y); // == -(h * 2 / d) h_x2_div_d = -sqrt(h_x2_div_d) / hypot_f(x, y); // == -(h * 2 / d)
@@ -1091,7 +1085,7 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
gc_block.values.ijk[axis_1] = 0.5 * (y + (x * h_x2_div_d)); gc_block.values.ijk[axis_1] = 0.5 * (y + (x * h_x2_div_d));
} else { // Arc Center Format Offset Mode } else { // Arc Center Format Offset Mode
if (!(ijk_words & (bit(axis_0) | bit(axis_1)))) { if (!(ijk_words & (bit(axis_0) | bit(axis_1)))) {
FAIL(STATUS_GCODE_NO_OFFSETS_IN_PLANE); // [No offsets in plane] FAIL(Error::GcodeNoOffsetsInPlane); // [No offsets in plane]
} }
bit_false(value_words, (bit(GCodeWord::I) | bit(GCodeWord::J) | bit(GCodeWord::K))); bit_false(value_words, (bit(GCodeWord::I) | bit(GCodeWord::J) | bit(GCodeWord::K)));
// Convert IJK values to proper units. // Convert IJK values to proper units.
@@ -1112,10 +1106,10 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
float delta_r = fabs(target_r - gc_block.values.r); float delta_r = fabs(target_r - gc_block.values.r);
if (delta_r > 0.005) { if (delta_r > 0.005) {
if (delta_r > 0.5) { if (delta_r > 0.5) {
FAIL(STATUS_GCODE_INVALID_TARGET); // [Arc definition error] > 0.5mm FAIL(Error::GcodeInvalidTarget); // [Arc definition error] > 0.5mm
} }
if (delta_r > (0.001 * gc_block.values.r)) { if (delta_r > (0.001 * gc_block.values.r)) {
FAIL(STATUS_GCODE_INVALID_TARGET); // [Arc definition error] > 0.005mm AND 0.1% radius FAIL(Error::GcodeInvalidTarget); // [Arc definition error] > 0.005mm AND 0.1% radius
} }
} }
} }
@@ -1132,10 +1126,10 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
// an error, it issues an alarm to prevent further motion to the probe. It's also done there to // an error, it issues an alarm to prevent further motion to the probe. It's also done there to
// allow the planner buffer to empty and move off the probe trigger before another probing cycle. // allow the planner buffer to empty and move off the probe trigger before another probing cycle.
if (!axis_words) { if (!axis_words) {
FAIL(STATUS_GCODE_NO_AXIS_WORDS); // [No axis words] FAIL(Error::GcodeNoAxisWords); // [No axis words]
} }
if (isequal_position_vector(gc_state.position, gc_block.values.xyz)) { if (isequal_position_vector(gc_state.position, gc_block.values.xyz)) {
FAIL(STATUS_GCODE_INVALID_TARGET); // [Invalid target] FAIL(Error::GcodeInvalidTarget); // [Invalid target]
} }
break; break;
} }
@@ -1157,7 +1151,7 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
bit(GCodeWord::C))); // Remove axis words. bit(GCodeWord::C))); // Remove axis words.
} }
if (value_words) { if (value_words) {
FAIL(STATUS_GCODE_UNUSED_WORDS); // [Unused words] FAIL(Error::GcodeUnusedWords); // [Unused words]
} }
/* ------------------------------------------------------------------------------------- /* -------------------------------------------------------------------------------------
STEP 4: EXECUTE!! STEP 4: EXECUTE!!
@@ -1176,17 +1170,17 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
// Only distance and unit modal commands and G53 absolute override command are allowed. // Only distance and unit modal commands and G53 absolute override command are allowed.
// NOTE: Feed rate word and axis word checks have already been performed in STEP 3. // NOTE: Feed rate word and axis word checks have already been performed in STEP 3.
if (command_words & ~(bit(ModalGroup::MG3) | bit(ModalGroup::MG6) | bit(ModalGroup::MG0))) { if (command_words & ~(bit(ModalGroup::MG3) | bit(ModalGroup::MG6) | bit(ModalGroup::MG0))) {
FAIL(STATUS_INVALID_JOG_COMMAND) FAIL(Error::InvalidJogCommand)
}; };
if (!(gc_block.non_modal_command == NonModal::AbsoluteOverride || gc_block.non_modal_command == NonModal::NoAction)) { if (!(gc_block.non_modal_command == NonModal::AbsoluteOverride || gc_block.non_modal_command == NonModal::NoAction)) {
FAIL(STATUS_INVALID_JOG_COMMAND); FAIL(Error::InvalidJogCommand);
} }
// Initialize planner data to current spindle and coolant modal state. // Initialize planner data to current spindle and coolant modal state.
pl_data->spindle_speed = gc_state.spindle_speed; pl_data->spindle_speed = gc_state.spindle_speed;
pl_data->spindle = gc_state.modal.spindle; pl_data->spindle = gc_state.modal.spindle;
pl_data->coolant = gc_state.modal.coolant; pl_data->coolant = gc_state.modal.coolant;
uint8_t status = jog_execute(pl_data, &gc_block); Error status = jog_execute(pl_data, &gc_block);
if (status == STATUS_OK) { if (status == Error::Ok) {
memcpy(gc_state.position, gc_block.values.xyz, sizeof(gc_block.values.xyz)); memcpy(gc_state.position, gc_block.values.xyz, sizeof(gc_block.values.xyz));
} }
return status; return status;
@@ -1296,7 +1290,7 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
if (gc_block.values.p <= MaxUserDigitalPin) { if (gc_block.values.p <= MaxUserDigitalPin) {
sys_io_control(bit((int)gc_block.values.p), (gc_block.modal.io_control == IoControl::Enable)); sys_io_control(bit((int)gc_block.values.p), (gc_block.modal.io_control == IoControl::Enable));
} else { } else {
FAIL(STATUS_P_PARAM_MAX_EXCEEDED); FAIL(Error::PParamMaxExceeded);
} }
} }
// [9. Override control ]: NOT SUPPORTED. Always enabled. Except for a Grbl-only parking control. // [9. Override control ]: NOT SUPPORTED. Always enabled. Except for a Grbl-only parking control.
@@ -1480,7 +1474,7 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
// Execute coordinate change and spindle/coolant stop. // Execute coordinate change and spindle/coolant stop.
if (sys.state != STATE_CHECK_MODE) { if (sys.state != STATE_CHECK_MODE) {
if (!(settings_read_coord_data(gc_state.modal.coord_select, gc_state.coord_system))) { if (!(settings_read_coord_data(gc_state.modal.coord_select, gc_state.coord_system))) {
FAIL(STATUS_SETTING_READ_FAIL); FAIL(Error::SettingReadFail);
} }
system_flag_wco_change(); // Set to refresh immediately just in case something altered. system_flag_wco_change(); // Set to refresh immediately just in case something altered.
spindle->set_state(SpindleState::Disable, 0); spindle->set_state(SpindleState::Disable, 0);
@@ -1495,7 +1489,7 @@ uint8_t gc_execute_line(char* line, uint8_t client) {
gc_state.modal.program_flow = ProgramFlow::Running; // Reset program flow. gc_state.modal.program_flow = ProgramFlow::Running; // Reset program flow.
// TODO: % to denote start of program. // TODO: % to denote start of program.
return STATUS_OK; return Error::Ok;
} }
/* /*

View File

@@ -304,7 +304,7 @@ enum class AxisCommand : uint8_t {
void gc_init(); void gc_init();
// Execute one block of rs275/ngc/g-code // Execute one block of rs275/ngc/g-code
uint8_t gc_execute_line(char* line, uint8_t client); Error gc_execute_line(char* line, uint8_t client);
// Set g-code parser position. Input in steps. // Set g-code parser position. Input in steps.
void gc_sync_position(); void gc_sync_position();

View File

@@ -40,6 +40,7 @@
#include "NutsBolts.h" #include "NutsBolts.h"
#include "Defaults.h" #include "Defaults.h"
#include "Error.h"
#include "SettingsStorage.h" #include "SettingsStorage.h"
#include "WebUI/Authentication.h" #include "WebUI/Authentication.h"
#include "WebUI/Commands.h" #include "WebUI/Commands.h"

View File

@@ -24,7 +24,7 @@
#include "Grbl.h" #include "Grbl.h"
// Sets up valid jog motion received from g-code parser, checks for soft-limits, and executes the jog. // Sets up valid jog motion received from g-code parser, checks for soft-limits, and executes the jog.
uint8_t jog_execute(plan_line_data_t* pl_data, parser_block_t* gc_block) { Error jog_execute(plan_line_data_t* pl_data, parser_block_t* gc_block) {
// Initialize planner data struct for jogging motions. // Initialize planner data struct for jogging motions.
// NOTE: Spindle and coolant are allowed to fully function with overrides during a jog. // NOTE: Spindle and coolant are allowed to fully function with overrides during a jog.
pl_data->feed_rate = gc_block->values.f; pl_data->feed_rate = gc_block->values.f;
@@ -34,7 +34,7 @@ uint8_t jog_execute(plan_line_data_t* pl_data, parser_block_t* gc_block) {
#endif #endif
if (soft_limits->get()) { if (soft_limits->get()) {
if (system_check_travel_limits(gc_block->values.xyz)) { if (system_check_travel_limits(gc_block->values.xyz)) {
return STATUS_TRAVEL_EXCEEDED; return Error::TravelExceeded;
} }
} }
// Valid jog command. Plan, set state, and execute. // Valid jog command. Plan, set state, and execute.
@@ -46,5 +46,5 @@ uint8_t jog_execute(plan_line_data_t* pl_data, parser_block_t* gc_block) {
st_wake_up(); // NOTE: Manual start. No state machine required. st_wake_up(); // NOTE: Manual start. No state machine required.
} }
} }
return STATUS_OK; return Error::Ok;
} }

View File

@@ -28,4 +28,4 @@
#define JOG_LINE_NUMBER 0 #define JOG_LINE_NUMBER 0
// Sets up valid jog motion received from g-code parser, checks for soft-limits, and executes the jog. // Sets up valid jog motion received from g-code parser, checks for soft-limits, and executes the jog.
uint8_t jog_execute(plan_line_data_t* pl_data, parser_block_t* gc_block); Error jog_execute(plan_line_data_t* pl_data, parser_block_t* gc_block);

View File

@@ -96,10 +96,10 @@ void settings_init() {
// sent to gc_execute_line. It is probably also more time-critical // sent to gc_execute_line. It is probably also more time-critical
// than actual settings, which change infrequently, so handling // than actual settings, which change infrequently, so handling
// it early is probably prudent. // it early is probably prudent.
uint8_t jog_set(uint8_t* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error jog_set(uint8_t* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
// Execute only if in IDLE or JOG states. // Execute only if in IDLE or JOG states.
if (sys.state != STATE_IDLE && sys.state != STATE_JOG) { if (sys.state != STATE_IDLE && sys.state != STATE_JOG) {
return STATUS_IDLE_ERROR; return Error::IdleError;
} }
// restore the $J= prefix because gc_execute_line() expects it // restore the $J= prefix because gc_execute_line() expects it
@@ -111,14 +111,14 @@ uint8_t jog_set(uint8_t* value, WebUI::AuthenticationLevel auth_level, WebUI::ES
return gc_execute_line(line, out->client()); // NOTE: $J= is ignored inside g-code parser and used to detect jog motions. return gc_execute_line(line, out->client()); // NOTE: $J= is ignored inside g-code parser and used to detect jog motions.
} }
err_t show_grbl_help(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error show_grbl_help(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
report_grbl_help(out->client()); report_grbl_help(out->client());
return STATUS_OK; return Error::Ok;
} }
err_t report_gcode(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error report_gcode(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
report_gcode_modes(out->client()); report_gcode_modes(out->client());
return STATUS_OK; return Error::Ok;
} }
void show_grbl_settings(WebUI::ESPResponseStream* out, type_t type, bool wantAxis) { void show_grbl_settings(WebUI::ESPResponseStream* out, type_t type, bool wantAxis) {
@@ -133,35 +133,35 @@ void show_grbl_settings(WebUI::ESPResponseStream* out, type_t type, bool wantAxi
} }
} }
} }
err_t report_normal_settings(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error report_normal_settings(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
show_grbl_settings(out, GRBL, false); // GRBL non-axis settings show_grbl_settings(out, GRBL, false); // GRBL non-axis settings
show_grbl_settings(out, GRBL, true); // GRBL axis settings show_grbl_settings(out, GRBL, true); // GRBL axis settings
return STATUS_OK; return Error::Ok;
} }
err_t report_extended_settings(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error report_extended_settings(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
show_grbl_settings(out, GRBL, false); // GRBL non-axis settings show_grbl_settings(out, GRBL, false); // GRBL non-axis settings
show_grbl_settings(out, EXTENDED, false); // Extended non-axis settings show_grbl_settings(out, EXTENDED, false); // Extended non-axis settings
show_grbl_settings(out, GRBL, true); // GRBL axis settings show_grbl_settings(out, GRBL, true); // GRBL axis settings
show_grbl_settings(out, EXTENDED, true); // Extended axis settings show_grbl_settings(out, EXTENDED, true); // Extended axis settings
return STATUS_OK; return Error::Ok;
} }
err_t list_grbl_names(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error list_grbl_names(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
for (Setting* s = Setting::List; s; s = s->next()) { for (Setting* s = Setting::List; s; s = s->next()) {
const char* gn = s->getGrblName(); const char* gn = s->getGrblName();
if (gn) { if (gn) {
grbl_sendf(out->client(), "$%s => $%s\r\n", gn, s->getName()); grbl_sendf(out->client(), "$%s => $%s\r\n", gn, s->getName());
} }
} }
return STATUS_OK; return Error::Ok;
} }
err_t list_settings(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error list_settings(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
for (Setting* s = Setting::List; s; s = s->next()) { for (Setting* s = Setting::List; s; s = s->next()) {
const char* displayValue = auth_failed(s, value, auth_level) ? "<Authentication required>" : s->getStringValue(); const char* displayValue = auth_failed(s, value, auth_level) ? "<Authentication required>" : s->getStringValue();
show_setting(s->getName(), displayValue, NULL, out); show_setting(s->getName(), displayValue, NULL, out);
} }
return STATUS_OK; return Error::Ok;
} }
err_t list_commands(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error list_commands(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
for (Command* cp = Command::List; cp; cp = cp->next()) { for (Command* cp = Command::List; cp; cp = cp->next()) {
const char* name = cp->getName(); const char* name = cp->getName();
const char* oldName = cp->getGrblName(); const char* oldName = cp->getGrblName();
@@ -176,9 +176,9 @@ err_t list_commands(const char* value, WebUI::AuthenticationLevel auth_level, We
} }
grbl_sendf(out->client(), "\r\n"); grbl_sendf(out->client(), "\r\n");
} }
return STATUS_OK; return Error::Ok;
} }
err_t toggle_check_mode(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error toggle_check_mode(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
// Perform reset when toggling off. Check g-code mode should only work if Grbl // Perform reset when toggling off. Check g-code mode should only work if Grbl
// is idle and ready, regardless of alarm locks. This is mainly to keep things // is idle and ready, regardless of alarm locks. This is mainly to keep things
// simple and consistent. // simple and consistent.
@@ -187,35 +187,35 @@ err_t toggle_check_mode(const char* value, WebUI::AuthenticationLevel auth_level
report_feedback_message(MESSAGE_DISABLED); report_feedback_message(MESSAGE_DISABLED);
} else { } else {
if (sys.state) { if (sys.state) {
return STATUS_IDLE_ERROR; // Requires no alarm mode. return Error::IdleError; // Requires no alarm mode.
} }
sys.state = STATE_CHECK_MODE; sys.state = STATE_CHECK_MODE;
report_feedback_message(MESSAGE_ENABLED); report_feedback_message(MESSAGE_ENABLED);
} }
return STATUS_OK; return Error::Ok;
} }
err_t disable_alarm_lock(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error disable_alarm_lock(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
if (sys.state == STATE_ALARM) { if (sys.state == STATE_ALARM) {
// Block if safety door is ajar. // Block if safety door is ajar.
if (system_check_safety_door_ajar()) { if (system_check_safety_door_ajar()) {
return STATUS_CHECK_DOOR; return Error::CheckDoor;
} }
report_feedback_message(MESSAGE_ALARM_UNLOCK); report_feedback_message(MESSAGE_ALARM_UNLOCK);
sys.state = STATE_IDLE; sys.state = STATE_IDLE;
// Don't run startup script. Prevents stored moves in startup from causing accidents. // Don't run startup script. Prevents stored moves in startup from causing accidents.
} // Otherwise, no effect. } // Otherwise, no effect.
return STATUS_OK; return Error::Ok;
} }
err_t report_ngc(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error report_ngc(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
report_ngc_parameters(out->client()); report_ngc_parameters(out->client());
return STATUS_OK; return Error::Ok;
} }
err_t home(int cycle) { Error home(int cycle) {
if (homing_enable->get() == false) { if (homing_enable->get() == false) {
return STATUS_SETTING_DISABLED; return Error::SettingDisabled;
} }
if (system_check_safety_door_ajar()) { if (system_check_safety_door_ajar()) {
return STATUS_CHECK_DOOR; // Block if safety door is ajar. return Error::CheckDoor; // Block if safety door is ajar.
} }
sys.state = STATE_HOMING; // Set system state variable sys.state = STATE_HOMING; // Set system state variable
#ifdef USE_I2S_STEPS #ifdef USE_I2S_STEPS
@@ -240,51 +240,51 @@ err_t home(int cycle) {
system_execute_startup(line); system_execute_startup(line);
} }
} }
return STATUS_OK; return Error::Ok;
} }
err_t home_all(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error home_all(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
return home(HOMING_CYCLE_ALL); return home(HOMING_CYCLE_ALL);
} }
err_t home_x(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error home_x(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
return home(X_AXIS); return home(X_AXIS);
} }
err_t home_y(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error home_y(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
return home(Y_AXIS); return home(Y_AXIS);
} }
err_t home_z(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error home_z(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
return home(Z_AXIS); return home(Z_AXIS);
} }
err_t home_a(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error home_a(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
return home(A_AXIS); return home(A_AXIS);
} }
err_t home_b(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error home_b(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
return home(B_AXIS); return home(B_AXIS);
} }
err_t home_c(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error home_c(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
return home(C_AXIS); return home(C_AXIS);
} }
err_t sleep_grbl(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error sleep_grbl(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
system_set_exec_state_flag(EXEC_SLEEP); system_set_exec_state_flag(EXEC_SLEEP);
return STATUS_OK; return Error::Ok;
} }
err_t get_report_build_info(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error get_report_build_info(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
if (!value) { if (!value) {
char line[128]; char line[128];
settings_read_build_info(line); settings_read_build_info(line);
report_build_info(line, out->client()); report_build_info(line, out->client());
return STATUS_OK; return Error::Ok;
} }
#ifdef ENABLE_BUILD_INFO_WRITE_COMMAND #ifdef ENABLE_BUILD_INFO_WRITE_COMMAND
settings_store_build_info(value); settings_store_build_info(value);
return STATUS_OK; return Error::Ok;
#else #else
return STATUS_INVALID_STATEMENT; return Error::InvalidStatement;
#endif #endif
} }
err_t report_startup_lines(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error report_startup_lines(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
report_startup_line(0, startup_line_0->get(), out->client()); report_startup_line(0, startup_line_0->get(), out->client());
report_startup_line(1, startup_line_1->get(), out->client()); report_startup_line(1, startup_line_1->get(), out->client());
return STATUS_OK; return Error::Ok;
} }
std::map<const char*, uint8_t, cmp_str> restoreCommands = { std::map<const char*, uint8_t, cmp_str> restoreCommands = {
@@ -299,29 +299,29 @@ std::map<const char*, uint8_t, cmp_str> restoreCommands = {
#endif #endif
{ "@", SETTINGS_RESTORE_WIFI_SETTINGS }, { "wifi", SETTINGS_RESTORE_WIFI_SETTINGS }, { "@", SETTINGS_RESTORE_WIFI_SETTINGS }, { "wifi", SETTINGS_RESTORE_WIFI_SETTINGS },
}; };
err_t restore_settings(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error restore_settings(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
if (!value) { if (!value) {
return STATUS_INVALID_STATEMENT; return Error::InvalidStatement;
} }
auto it = restoreCommands.find(value); auto it = restoreCommands.find(value);
if (it == restoreCommands.end()) { if (it == restoreCommands.end()) {
return STATUS_INVALID_STATEMENT; return Error::InvalidStatement;
} }
settings_restore(it->second); settings_restore(it->second);
return STATUS_OK; return Error::Ok;
} }
err_t showState(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error showState(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
grbl_sendf(out->client(), "State 0x%x\r\n", sys.state); grbl_sendf(out->client(), "State 0x%x\r\n", sys.state);
return STATUS_OK; return Error::Ok;
} }
err_t doJog(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error doJog(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
// For jogging, you must give gc_execute_line() a line that // For jogging, you must give gc_execute_line() a line that
// begins with $J=. There are several ways we can get here, // begins with $J=. There are several ways we can get here,
// including $J, $J=xxx, [J]xxx. For any form other than // including $J, $J=xxx, [J]xxx. For any form other than
// $J without =, we reconstruct a $J= line for gc_execute_line(). // $J without =, we reconstruct a $J= line for gc_execute_line().
if (!value) { if (!value) {
return STATUS_INVALID_STATEMENT; return Error::InvalidStatement;
} }
char jogLine[LINE_BUFFER_SIZE]; char jogLine[LINE_BUFFER_SIZE];
strcpy(jogLine, "$J="); strcpy(jogLine, "$J=");
@@ -329,91 +329,33 @@ err_t doJog(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESP
return gc_execute_line(jogLine, out->client()); return gc_execute_line(jogLine, out->client());
} }
std::map<uint8_t, const char*> ErrorCodes = { const char* errorString(Error errorNumber) {
{ STATUS_OK, "No error" },
{ STATUS_EXPECTED_COMMAND_LETTER, "Expected GCodecommand letter" },
{ STATUS_BAD_NUMBER_FORMAT, "Bad GCode number format" },
{ STATUS_INVALID_STATEMENT, "Invalid $ statement" },
{ STATUS_NEGATIVE_VALUE, "Negative value" },
{ STATUS_SETTING_DISABLED, "Setting disabled" },
{ STATUS_SETTING_STEP_PULSE_MIN, "Step pulse too short" },
{ STATUS_SETTING_READ_FAIL, "Failed to read settings" },
{ STATUS_IDLE_ERROR, "Command requires idle state" },
{ STATUS_SYSTEM_GC_LOCK, "GCode cannot be executed in lock or alarm state" },
{ STATUS_SOFT_LIMIT_ERROR, "Soft limit error" },
{ STATUS_OVERFLOW, "Line too long" },
{ STATUS_MAX_STEP_RATE_EXCEEDED, "Max step rate exceeded" },
{ STATUS_CHECK_DOOR, "Check door" },
{ STATUS_LINE_LENGTH_EXCEEDED, "Startup line too long" },
{ STATUS_TRAVEL_EXCEEDED, "Max travel exceeded during jog" },
{ STATUS_INVALID_JOG_COMMAND, "Invalid jog command" },
{ STATUS_SETTING_DISABLED_LASER, "Laser mode requires PWM output" },
{ STATUS_GCODE_UNSUPPORTED_COMMAND, "Unsupported GCode command" },
{ STATUS_GCODE_MODAL_GROUP_VIOLATION, "Gcode modal group violation" },
{ STATUS_GCODE_UNDEFINED_FEED_RATE, "Gcode undefined feed rate" },
{ STATUS_GCODE_COMMAND_VALUE_NOT_INTEGER, "Gcode command value not integer" },
{ STATUS_GCODE_AXIS_COMMAND_CONFLICT, "Gcode axis command conflict" },
{ STATUS_GCODE_WORD_REPEATED, "Gcode word repeated" },
{ STATUS_GCODE_NO_AXIS_WORDS, "Gcode no axis words" },
{ STATUS_GCODE_INVALID_LINE_NUMBER, "Gcode invalid line number" },
{ STATUS_GCODE_VALUE_WORD_MISSING, "Gcode value word missing" },
{ STATUS_GCODE_UNSUPPORTED_COORD_SYS, "Gcode unsupported coordinate system" },
{ STATUS_GCODE_G53_INVALID_MOTION_MODE, "Gcode G53 invalid motion mode" },
{ STATUS_GCODE_AXIS_WORDS_EXIST, "Gcode extra axis words" },
{ STATUS_GCODE_NO_AXIS_WORDS_IN_PLANE, "Gcode no axis words in plane" },
{ STATUS_GCODE_INVALID_TARGET, "Gcode invalid target" },
{ STATUS_GCODE_ARC_RADIUS_ERROR, "Gcode arc radius error" },
{ STATUS_GCODE_NO_OFFSETS_IN_PLANE, "Gcode no offsets in plane" },
{ STATUS_GCODE_UNUSED_WORDS, "Gcode unused words" },
{ STATUS_GCODE_G43_DYNAMIC_AXIS_ERROR, "Gcode G43 dynamic axis error" },
{ STATUS_GCODE_MAX_VALUE_EXCEEDED, "Gcode max value exceeded" },
{ STATUS_P_PARAM_MAX_EXCEEDED, "P param max exceeded" },
{ STATUS_SD_FAILED_MOUNT, "SD failed mount" },
{ STATUS_SD_FAILED_READ, "SD failed read" },
{ STATUS_SD_FAILED_OPEN_DIR, "SD failed to open directory" },
{ STATUS_SD_DIR_NOT_FOUND, "SD directory not found" },
{ STATUS_SD_FILE_EMPTY, "SD file empty" },
{ STATUS_SD_FILE_NOT_FOUND, "SD file not found" },
{ STATUS_SD_FAILED_OPEN_FILE, "SD failed to open file" },
{ STATUS_SD_FAILED_BUSY, "SD is busy" },
{ STATUS_SD_FAILED_DEL_DIR, "SD failed to delete directory" },
{ STATUS_SD_FAILED_DEL_FILE, "SD failed to delete file" },
{ STATUS_BT_FAIL_BEGIN, "Bluetooth failed to start" },
{ STATUS_WIFI_FAIL_BEGIN, "WiFi failed to start" },
{ STATUS_NUMBER_RANGE, "Number out of range for setting" },
{ STATUS_INVALID_VALUE, "Invalid value for setting" },
{ STATUS_MESSAGE_FAILED, "Failed to send message" },
{ STATUS_NVS_SET_FAILED, "Failed to store setting" },
{ STATUS_AUTHENTICATION_FAILED, "Authentication failed!" },
};
const char* errorString(err_t errorNumber) {
auto it = ErrorCodes.find(errorNumber); auto it = ErrorCodes.find(errorNumber);
return it == ErrorCodes.end() ? NULL : it->second; return it == ErrorCodes.end() ? NULL : it->second;
} }
err_t listErrorCodes(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error listErrorCodes(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
if (value) { if (value) {
char* endptr = NULL; char* endptr = NULL;
uint8_t errorNumber = strtol(value, &endptr, 10); uint8_t errorNumber = strtol(value, &endptr, 10);
if (*endptr) { if (*endptr) {
grbl_sendf(out->client(), "Malformed error number: %s\r\n", value); grbl_sendf(out->client(), "Malformed error number: %s\r\n", value);
return STATUS_INVALID_VALUE; return Error::InvalidValue;
} }
const char* errorName = errorString(errorNumber); const char* errorName = errorString(static_cast<Error>(errorNumber));
if (errorName) { if (errorName) {
grbl_sendf(out->client(), "%d: %s\r\n", errorNumber, errorName); grbl_sendf(out->client(), "%d: %s\r\n", errorNumber, errorName);
return STATUS_OK; return Error::Ok;
} else { } else {
grbl_sendf(out->client(), "Unknown error number: %d\r\n", errorNumber); grbl_sendf(out->client(), "Unknown error number: %d\r\n", errorNumber);
return STATUS_INVALID_VALUE; return Error::InvalidValue;
} }
} }
for (auto it = ErrorCodes.begin(); it != ErrorCodes.end(); it++) { for (auto it = ErrorCodes.begin(); it != ErrorCodes.end(); it++) {
grbl_sendf(out->client(), "%d: %s\r\n", it->first, it->second); grbl_sendf(out->client(), "%d: %s\r\n", it->first, it->second);
} }
return STATUS_OK; return Error::Ok;
} }
// Commands use the same syntax as Settings, but instead of setting or // Commands use the same syntax as Settings, but instead of setting or
@@ -493,7 +435,7 @@ char* normalize_key(char* start) {
// This is the handler for all forms of settings commands, // This is the handler for all forms of settings commands,
// $..= and [..], with and without a value. // $..= and [..], with and without a value.
err_t do_command_or_setting(const char* key, char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error do_command_or_setting(const char* key, char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
// If value is NULL, it means that there was no value string, i.e. // If value is NULL, it means that there was no value string, i.e.
// $key without =, or [key] with nothing following. // $key without =, or [key] with nothing following.
// If value is not NULL, but the string is empty, that is the form // If value is not NULL, but the string is empty, that is the form
@@ -505,13 +447,13 @@ err_t do_command_or_setting(const char* key, char* value, WebUI::AuthenticationL
for (Setting* s = Setting::List; s; s = s->next()) { for (Setting* s = Setting::List; s; s = s->next()) {
if (strcasecmp(s->getName(), key) == 0) { if (strcasecmp(s->getName(), key) == 0) {
if (auth_failed(s, value, auth_level)) { if (auth_failed(s, value, auth_level)) {
return STATUS_AUTHENTICATION_FAILED; return Error::AuthenticationFailed;
} }
if (value) { if (value) {
return s->setStringValue(value); return s->setStringValue(value);
} else { } else {
show_setting(s->getName(), s->getStringValue(), NULL, out); show_setting(s->getName(), s->getStringValue(), NULL, out);
return STATUS_OK; return Error::Ok;
} }
} }
} }
@@ -521,13 +463,13 @@ err_t do_command_or_setting(const char* key, char* value, WebUI::AuthenticationL
for (Setting* s = Setting::List; s; s = s->next()) { for (Setting* s = Setting::List; s; s = s->next()) {
if (s->getGrblName() && strcasecmp(s->getGrblName(), key) == 0) { if (s->getGrblName() && strcasecmp(s->getGrblName(), key) == 0) {
if (auth_failed(s, value, auth_level)) { if (auth_failed(s, value, auth_level)) {
return STATUS_AUTHENTICATION_FAILED; return Error::AuthenticationFailed;
} }
if (value) { if (value) {
return s->setStringValue(value); return s->setStringValue(value);
} else { } else {
show_setting(s->getGrblName(), s->getCompatibleValue(), NULL, out); show_setting(s->getGrblName(), s->getCompatibleValue(), NULL, out);
return STATUS_OK; return Error::Ok;
} }
} }
} }
@@ -537,7 +479,7 @@ err_t do_command_or_setting(const char* key, char* value, WebUI::AuthenticationL
for (Command* cp = Command::List; cp; cp = cp->next()) { for (Command* cp = Command::List; cp; cp = cp->next()) {
if ((strcasecmp(cp->getName(), key) == 0) || (cp->getGrblName() && strcasecmp(cp->getGrblName(), key) == 0)) { if ((strcasecmp(cp->getName(), key) == 0) || (cp->getGrblName() && strcasecmp(cp->getGrblName(), key) == 0)) {
if (auth_failed(cp, value, auth_level)) { if (auth_failed(cp, value, auth_level)) {
return STATUS_AUTHENTICATION_FAILED; return Error::AuthenticationFailed;
} }
return cp->action(value, auth_level, out); return cp->action(value, auth_level, out);
} }
@@ -547,7 +489,7 @@ err_t do_command_or_setting(const char* key, char* value, WebUI::AuthenticationL
// indicating a display operation, we allow partial matches // indicating a display operation, we allow partial matches
// and display every possibility. This only applies to the // and display every possibility. This only applies to the
// text form of the name, not to the nnn and ESPnnn forms. // text form of the name, not to the nnn and ESPnnn forms.
err_t retval = STATUS_INVALID_STATEMENT; Error retval = Error::InvalidStatement;
if (!value) { if (!value) {
auto lcKey = String(key); auto lcKey = String(key);
// We allow the key string to begin with *, which we remove. // We allow the key string to begin with *, which we remove.
@@ -569,13 +511,13 @@ err_t do_command_or_setting(const char* key, char* value, WebUI::AuthenticationL
} }
} }
if (found) { if (found) {
return STATUS_OK; return Error::Ok;
} }
} }
return STATUS_INVALID_STATEMENT; return Error::InvalidStatement;
} }
uint8_t system_execute_line(char* line, WebUI::ESPResponseStream* out, WebUI::AuthenticationLevel auth_level) { Error system_execute_line(char* line, WebUI::ESPResponseStream* out, WebUI::AuthenticationLevel auth_level) {
remove_password(line, auth_level); remove_password(line, auth_level);
char* value; char* value;
@@ -583,7 +525,7 @@ uint8_t system_execute_line(char* line, WebUI::ESPResponseStream* out, WebUI::Au
value = strrchr(line, ']'); value = strrchr(line, ']');
if (!value) { if (!value) {
// Missing ] is an error in this form // Missing ] is an error in this form
return STATUS_INVALID_STATEMENT; return Error::InvalidStatement;
} }
// ']' was found; replace it with null and set value to the rest of the line. // ']' was found; replace it with null and set value to the rest of the line.
*value++ = '\0'; *value++ = '\0';
@@ -609,12 +551,12 @@ uint8_t system_execute_line(char* line, WebUI::ESPResponseStream* out, WebUI::Au
// non-empty string - [ESPxxx]yyy or $xxx=yyy // non-empty string - [ESPxxx]yyy or $xxx=yyy
return do_command_or_setting(key, value, auth_level, out); return do_command_or_setting(key, value, auth_level, out);
} }
uint8_t system_execute_line(char* line, uint8_t client, WebUI::AuthenticationLevel auth_level) { Error system_execute_line(char* line, uint8_t client, WebUI::AuthenticationLevel auth_level) {
return system_execute_line(line, new WebUI::ESPResponseStream(client, true), auth_level); return system_execute_line(line, new WebUI::ESPResponseStream(client, true), auth_level);
} }
void system_execute_startup(char* line) { void system_execute_startup(char* line) {
err_t status_code; Error status_code;
char gcline[256]; char gcline[256];
strncpy(gcline, startup_line_0->get(), 255); strncpy(gcline, startup_line_0->get(), 255);
if (*gcline) { if (*gcline) {

View File

@@ -50,7 +50,7 @@ static void empty_lines() {
} }
} }
err_t add_char_to_line(char c, uint8_t client) { Error add_char_to_line(char c, uint8_t client) {
client_line_t* cl = &client_lines[client]; client_line_t* cl = &client_lines[client];
// Simple editing for interactive input // Simple editing for interactive input
if (c == '\b') { if (c == '\b') {
@@ -59,26 +59,26 @@ err_t add_char_to_line(char c, uint8_t client) {
--cl->len; --cl->len;
cl->buffer[cl->len] = '\0'; cl->buffer[cl->len] = '\0';
} }
return STATUS_OK; return Error::Ok;
} }
if (cl->len == (LINE_BUFFER_SIZE - 1)) { if (cl->len == (LINE_BUFFER_SIZE - 1)) {
return STATUS_OVERFLOW; return Error::Overflow;
} }
if (c == '\r' || c == '\n') { if (c == '\r' || c == '\n') {
cl->len = 0; cl->len = 0;
cl->line_number++; cl->line_number++;
return STATUS_EOL; return Error::Eol;
} }
cl->buffer[cl->len++] = c; cl->buffer[cl->len++] = c;
cl->buffer[cl->len] = '\0'; cl->buffer[cl->len] = '\0';
return STATUS_OK; return Error::Ok;
} }
err_t execute_line(char* line, uint8_t client, WebUI::AuthenticationLevel auth_level) { Error execute_line(char* line, uint8_t client, WebUI::AuthenticationLevel auth_level) {
err_t result = STATUS_OK; Error result = Error::Ok;
// Empty or comment line. For syncing purposes. // Empty or comment line. For syncing purposes.
if (line[0] == 0) { if (line[0] == 0) {
return STATUS_OK; return Error::Ok;
} }
// Grbl '$' or WebUI '[ESPxxx]' system command // Grbl '$' or WebUI '[ESPxxx]' system command
if (line[0] == '$' || line[0] == '[') { if (line[0] == '$' || line[0] == '[') {
@@ -86,7 +86,7 @@ err_t execute_line(char* line, uint8_t client, WebUI::AuthenticationLevel auth_l
} }
// Everything else is gcode. Block if in alarm or jog mode. // Everything else is gcode. Block if in alarm or jog mode.
if (sys.state & (STATE_ALARM | STATE_JOG)) { if (sys.state & (STATE_ALARM | STATE_JOG)) {
return STATUS_SYSTEM_GC_LOCK; return Error::SystemGcLock;
} }
return gc_execute_line(line, client); return gc_execute_line(line, client);
} }
@@ -158,10 +158,10 @@ void protocol_main_loop() {
char* line; char* line;
for (client = 0; client < CLIENT_COUNT; client++) { for (client = 0; client < CLIENT_COUNT; client++) {
while ((c = serial_read(client)) != SERIAL_NO_DATA) { while ((c = serial_read(client)) != SERIAL_NO_DATA) {
err_t res = add_char_to_line(c, client); Error res = add_char_to_line(c, client);
switch (res) { switch (res) {
case STATUS_OK: break; case Error::Ok: break;
case STATUS_EOL: case Error::Eol:
protocol_execute_realtime(); // Runtime command check point. protocol_execute_realtime(); // Runtime command check point.
if (sys.abort) { if (sys.abort) {
return; // Bail to calling function upon system abort return; // Bail to calling function upon system abort
@@ -174,10 +174,11 @@ void protocol_main_loop() {
report_status_message(execute_line(line, client, WebUI::AuthenticationLevel::LEVEL_GUEST), client); report_status_message(execute_line(line, client, WebUI::AuthenticationLevel::LEVEL_GUEST), client);
empty_line(client); empty_line(client);
break; break;
case STATUS_OVERFLOW: case Error::Overflow:
report_status_message(STATUS_OVERFLOW, client); report_status_message(Error::Overflow, client);
empty_line(client); empty_line(client);
break; break;
default: break;
} }
} // while serial read } // while serial read
} // for clients } // for clients

View File

@@ -206,9 +206,9 @@ void get_state(char* foo) {
// operation. Errors events can originate from the g-code parser, settings module, or asynchronously // operation. Errors events can originate from the g-code parser, settings module, or asynchronously
// from a critical error, such as a triggered hard limit. Interface should always monitor for these // from a critical error, such as a triggered hard limit. Interface should always monitor for these
// responses. // responses.
void report_status_message(uint8_t status_code, uint8_t client) { void report_status_message(Error status_code, uint8_t client) {
switch (status_code) { switch (status_code) {
case STATUS_OK: // STATUS_OK case Error::Ok: // Error::Ok
#ifdef ENABLE_SD_CARD #ifdef ENABLE_SD_CARD
if (get_sd_state(false) == SDCARD_BUSY_PRINTING) { if (get_sd_state(false) == SDCARD_BUSY_PRINTING) {
SD_ready_next = true; // flag so system_execute_line() will send the next line SD_ready_next = true; // flag so system_execute_line() will send the next line
@@ -223,7 +223,7 @@ void report_status_message(uint8_t status_code, uint8_t client) {
#ifdef ENABLE_SD_CARD #ifdef ENABLE_SD_CARD
// do we need to stop a running SD job? // do we need to stop a running SD job?
if (get_sd_state(false) == SDCARD_BUSY_PRINTING) { if (get_sd_state(false) == SDCARD_BUSY_PRINTING) {
if (status_code == STATUS_GCODE_UNSUPPORTED_COMMAND) { if (status_code == Error::GcodeUnsupportedCommand) {
grbl_sendf(client, "error:%d\r\n", status_code); // most senders seem to tolerate this error and keep on going grbl_sendf(client, "error:%d\r\n", status_code); // most senders seem to tolerate this error and keep on going
grbl_sendf(CLIENT_ALL, "error:%d in SD file at line %d\r\n", status_code, sd_get_current_line_number()); grbl_sendf(CLIENT_ALL, "error:%d in SD file at line %d\r\n", status_code, sd_get_current_line_number());
// don't close file // don't close file
@@ -235,7 +235,7 @@ void report_status_message(uint8_t status_code, uint8_t client) {
return; return;
} }
#endif #endif
grbl_sendf(client, "error:%d\r\n", status_code); grbl_sendf(client, "error:%d\r\n", static_cast<int>(status_code));
} }
} }
@@ -310,7 +310,7 @@ void report_ngc_parameters(uint8_t client) {
ngc_rpt[0] = '\0'; ngc_rpt[0] = '\0';
for (coord_select = 0; coord_select <= SETTING_INDEX_NCOORD; coord_select++) { for (coord_select = 0; coord_select <= SETTING_INDEX_NCOORD; coord_select++) {
if (!(settings_read_coord_data(coord_select, coord_data))) { if (!(settings_read_coord_data(coord_select, coord_data))) {
report_status_message(STATUS_SETTING_READ_FAIL, CLIENT_SERIAL); report_status_message(Error::SettingReadFail, CLIENT_SERIAL);
return; return;
} }
strcat(ngc_rpt, "[G"); strcat(ngc_rpt, "[G");
@@ -451,7 +451,7 @@ void report_startup_line(uint8_t n, const char* line, uint8_t client) {
grbl_sendf(client, "$N%d=%s\r\n", n, line); // OK to send to all grbl_sendf(client, "$N%d=%s\r\n", n, line); // OK to send to all
} }
void report_execute_startup_message(const char* line, uint8_t status_code, uint8_t client) { void report_execute_startup_message(const char* line, Error status_code, uint8_t client) {
grbl_sendf(client, ">%s:", line); // OK to send to all grbl_sendf(client, ">%s:", line); // OK to send to all
report_status_message(status_code, client); report_status_message(status_code, client);
} }

View File

@@ -20,73 +20,7 @@
along with Grbl. If not, see <http://www.gnu.org/licenses/>. along with Grbl. If not, see <http://www.gnu.org/licenses/>.
*/ */
// Define Grbl status codes. Valid values (0-255) const char* errorString(Error errorNumber);
#define STATUS_OK 0
#define STATUS_EXPECTED_COMMAND_LETTER 1
#define STATUS_BAD_NUMBER_FORMAT 2
#define STATUS_INVALID_STATEMENT 3
#define STATUS_NEGATIVE_VALUE 4
#define STATUS_SETTING_DISABLED 5
#define STATUS_SETTING_STEP_PULSE_MIN 6
#define STATUS_SETTING_READ_FAIL 7
#define STATUS_IDLE_ERROR 8
#define STATUS_SYSTEM_GC_LOCK 9
#define STATUS_SOFT_LIMIT_ERROR 10
#define STATUS_OVERFLOW 11
#define STATUS_MAX_STEP_RATE_EXCEEDED 12
#define STATUS_CHECK_DOOR 13
#define STATUS_LINE_LENGTH_EXCEEDED 14
#define STATUS_TRAVEL_EXCEEDED 15
#define STATUS_INVALID_JOG_COMMAND 16
#define STATUS_SETTING_DISABLED_LASER 17
#define STATUS_GCODE_UNSUPPORTED_COMMAND 20
#define STATUS_GCODE_MODAL_GROUP_VIOLATION 21
#define STATUS_GCODE_UNDEFINED_FEED_RATE 22
#define STATUS_GCODE_COMMAND_VALUE_NOT_INTEGER 23
#define STATUS_GCODE_AXIS_COMMAND_CONFLICT 24
#define STATUS_GCODE_WORD_REPEATED 25
#define STATUS_GCODE_NO_AXIS_WORDS 26
#define STATUS_GCODE_INVALID_LINE_NUMBER 27
#define STATUS_GCODE_VALUE_WORD_MISSING 28
#define STATUS_GCODE_UNSUPPORTED_COORD_SYS 29
#define STATUS_GCODE_G53_INVALID_MOTION_MODE 30
#define STATUS_GCODE_AXIS_WORDS_EXIST 31
#define STATUS_GCODE_NO_AXIS_WORDS_IN_PLANE 32
#define STATUS_GCODE_INVALID_TARGET 33
#define STATUS_GCODE_ARC_RADIUS_ERROR 34
#define STATUS_GCODE_NO_OFFSETS_IN_PLANE 35
#define STATUS_GCODE_UNUSED_WORDS 36
#define STATUS_GCODE_G43_DYNAMIC_AXIS_ERROR 37
#define STATUS_GCODE_MAX_VALUE_EXCEEDED 38
#define STATUS_P_PARAM_MAX_EXCEEDED 39
#define STATUS_SD_FAILED_MOUNT 60 // SD Failed to mount
#define STATUS_SD_FAILED_READ 61 // SD Failed to read file
#define STATUS_SD_FAILED_OPEN_DIR 62 // SD card failed to open directory
#define STATUS_SD_DIR_NOT_FOUND 63 // SD Card directory not found
#define STATUS_SD_FILE_EMPTY 64 // SD Card directory not found
#define STATUS_SD_FILE_NOT_FOUND 65 // SD Card file not found
#define STATUS_SD_FAILED_OPEN_FILE 66 // SD card failed to open file
#define STATUS_SD_FAILED_BUSY 67 // SD card is busy
#define STATUS_SD_FAILED_DEL_DIR 68
#define STATUS_SD_FAILED_DEL_FILE 69
#define STATUS_BT_FAIL_BEGIN 70 // Bluetooth failed to start
#define STATUS_WIFI_FAIL_BEGIN 71 // WiFi failed to start
#define STATUS_NUMBER_RANGE 80 // Setting number range problem
#define STATUS_INVALID_VALUE 81 // Setting string problem
#define STATUS_MESSAGE_FAILED 90
#define STATUS_NVS_SET_FAILED 100
#define STATUS_AUTHENTICATION_FAILED 110
#define STATUS_EOL 111
typedef uint8_t err_t; // For status codes
const char* errorString(err_t errorNumber);
// Define Grbl alarm codes. Valid values (1-255). 0 is reserved. // Define Grbl alarm codes. Valid values (1-255). 0 is reserved.
#define ALARM_HARD_LIMIT_ERROR EXEC_ALARM_HARD_LIMIT #define ALARM_HARD_LIMIT_ERROR EXEC_ALARM_HARD_LIMIT
@@ -138,7 +72,7 @@ void grbl_notify(const char* title, const char* msg);
void grbl_notifyf(const char* title, const char* format, ...); void grbl_notifyf(const char* title, const char* format, ...);
// Prints system status messages. // Prints system status messages.
void report_status_message(uint8_t status_code, uint8_t client); void report_status_message(Error status_code, uint8_t client);
void report_realtime_steps(); void report_realtime_steps();
// Prints system alarm messages. // Prints system alarm messages.
@@ -173,7 +107,7 @@ void report_gcode_modes(uint8_t client);
// Prints startup line when requested and executed. // Prints startup line when requested and executed.
void report_startup_line(uint8_t n, const char* line, uint8_t client); void report_startup_line(uint8_t n, const char* line, uint8_t client);
void report_execute_startup_message(const char* line, uint8_t status_code, uint8_t client); void report_execute_startup_message(const char* line, Error status_code, uint8_t client);
// Prints build info and user info // Prints build info and user info
void report_build_info(char* line, uint8_t client); void report_build_info(char* line, uint8_t client);

View File

@@ -30,7 +30,7 @@ static char comment[LINE_BUFFER_SIZE]; // Line to be executed. Zero-terminated.
/*bool sd_mount() /*bool sd_mount()
{ {
if(!SD.begin()) { if(!SD.begin()) {
report_status_message(STATUS_SD_FAILED_MOUNT, CLIENT_SERIAL); report_status_message(Error::SdFailedMount, CLIENT_SERIAL);
return false; return false;
} }
return true; return true;
@@ -40,11 +40,11 @@ void listDir(fs::FS& fs, const char* dirname, uint8_t levels, uint8_t client) {
//char temp_filename[128]; // to help filter by extension TODO: 128 needs a definition based on something //char temp_filename[128]; // to help filter by extension TODO: 128 needs a definition based on something
File root = fs.open(dirname); File root = fs.open(dirname);
if (!root) { if (!root) {
report_status_message(STATUS_SD_FAILED_OPEN_DIR, client); report_status_message(Error::SdFailedOpenDir, client);
return; return;
} }
if (!root.isDirectory()) { if (!root.isDirectory()) {
report_status_message(STATUS_SD_DIR_NOT_FOUND, client); report_status_message(Error::SdDirNotFound, client);
return; return;
} }
File file = root.openNextFile(); File file = root.openNextFile();
@@ -63,7 +63,7 @@ void listDir(fs::FS& fs, const char* dirname, uint8_t levels, uint8_t client) {
boolean openFile(fs::FS& fs, const char* path) { boolean openFile(fs::FS& fs, const char* path) {
myFile = fs.open(path); myFile = fs.open(path);
if (!myFile) { if (!myFile) {
//report_status_message(STATUS_SD_FAILED_READ, CLIENT_SERIAL); //report_status_message(Error::SdFailedRead, CLIENT_SERIAL);
return false; return false;
} }
set_sd_state(SDCARD_BUSY_PRINTING); set_sd_state(SDCARD_BUSY_PRINTING);
@@ -92,7 +92,7 @@ boolean closeFile() {
*/ */
boolean readFileLine(char* line, int maxlen) { boolean readFileLine(char* line, int maxlen) {
if (!myFile) { if (!myFile) {
report_status_message(STATUS_SD_FAILED_READ, SD_client); report_status_message(Error::SdFailedRead, SD_client);
return false; return false;
} }
sd_current_line_number += 1; sd_current_line_number += 1;

View File

@@ -40,14 +40,14 @@ Setting::Setting(
} }
} }
err_t Setting::check(char* s) { Error Setting::check(char* s) {
if (sys.state != STATE_IDLE && !(sys.state & STATE_ALARM)) { if (sys.state != STATE_IDLE && !(sys.state & STATE_ALARM)) {
return STATUS_IDLE_ERROR; return Error::IdleError;
} }
if (!_checker) { if (!_checker) {
return STATUS_OK; return Error::Ok;
} }
return _checker(s) ? STATUS_OK : STATUS_INVALID_VALUE; return _checker(s) ? Error::Ok : Error::InvalidValue;
} }
nvs_handle Setting::_handle = 0; nvs_handle Setting::_handle = 0;
@@ -89,18 +89,19 @@ void IntSetting::setDefault() {
} }
} }
err_t IntSetting::setStringValue(char* s) { Error IntSetting::setStringValue(char* s) {
s = trim(s); s = trim(s);
if (err_t err = check(s)) { Error err = check(s);
if (err != Error::Ok) {
return err; return err;
} }
char* endptr; char* endptr;
int32_t convertedValue = strtol(s, &endptr, 10); int32_t convertedValue = strtol(s, &endptr, 10);
if (endptr == s || *endptr != '\0') { if (endptr == s || *endptr != '\0') {
return STATUS_BAD_NUMBER_FORMAT; return Error::BadNumberFormat;
} }
if (convertedValue < _minValue || convertedValue > _maxValue) { if (convertedValue < _minValue || convertedValue > _maxValue) {
return STATUS_NUMBER_RANGE; return Error::NumberRange;
} }
_currentValue = convertedValue; _currentValue = convertedValue;
if (_storedValue != _currentValue) { if (_storedValue != _currentValue) {
@@ -108,12 +109,12 @@ err_t IntSetting::setStringValue(char* s) {
nvs_erase_key(_handle, _keyName); nvs_erase_key(_handle, _keyName);
} else { } else {
if (nvs_set_i32(_handle, _keyName, _currentValue)) { if (nvs_set_i32(_handle, _keyName, _currentValue)) {
return STATUS_NVS_SET_FAILED; return Error::NvsSetFailed;
} }
_storedValue = _currentValue; _storedValue = _currentValue;
} }
} }
return STATUS_OK; return Error::Ok;
} }
const char* IntSetting::getStringValue() { const char* IntSetting::getStringValue() {
@@ -156,9 +157,10 @@ void AxisMaskSetting::setDefault() {
} }
} }
err_t AxisMaskSetting::setStringValue(char* s) { Error AxisMaskSetting::setStringValue(char* s) {
s = trim(s); s = trim(s);
if (err_t err = check(s)) { Error err = check(s);
if (err != Error::Ok) {
return err; return err;
} }
int32_t convertedValue; int32_t convertedValue;
@@ -174,7 +176,7 @@ err_t AxisMaskSetting::setStringValue(char* s) {
while (*s) { while (*s) {
int index = axisNames.indexOf(toupper(*s++)); int index = axisNames.indexOf(toupper(*s++));
if (index < 0) { if (index < 0) {
return STATUS_BAD_NUMBER_FORMAT; return Error::BadNumberFormat;
} }
convertedValue |= bit(index); convertedValue |= bit(index);
} }
@@ -186,12 +188,12 @@ err_t AxisMaskSetting::setStringValue(char* s) {
nvs_erase_key(_handle, _keyName); nvs_erase_key(_handle, _keyName);
} else { } else {
if (nvs_set_i32(_handle, _keyName, _currentValue)) { if (nvs_set_i32(_handle, _keyName, _currentValue)) {
return STATUS_NVS_SET_FAILED; return Error::NvsSetFailed;
} }
_storedValue = _currentValue; _storedValue = _currentValue;
} }
} }
return STATUS_OK; return Error::Ok;
} }
const char* AxisMaskSetting::getCompatibleValue() { const char* AxisMaskSetting::getCompatibleValue() {
@@ -251,9 +253,10 @@ void FloatSetting::setDefault() {
} }
} }
err_t FloatSetting::setStringValue(char* s) { Error FloatSetting::setStringValue(char* s) {
s = trim(s); s = trim(s);
if (err_t err = check(s)) { Error err = check(s);
if (err != Error::Ok) {
return err; return err;
} }
@@ -261,10 +264,10 @@ err_t FloatSetting::setStringValue(char* s) {
uint8_t len = strlen(s); uint8_t len = strlen(s);
uint8_t retlen = 0; uint8_t retlen = 0;
if (!read_float(s, &retlen, &convertedValue) || retlen != len) { if (!read_float(s, &retlen, &convertedValue) || retlen != len) {
return STATUS_BAD_NUMBER_FORMAT; return Error::BadNumberFormat;
} }
if (convertedValue < _minValue || convertedValue > _maxValue) { if (convertedValue < _minValue || convertedValue > _maxValue) {
return STATUS_NUMBER_RANGE; return Error::NumberRange;
} }
_currentValue = convertedValue; _currentValue = convertedValue;
if (_storedValue != _currentValue) { if (_storedValue != _currentValue) {
@@ -277,12 +280,12 @@ err_t FloatSetting::setStringValue(char* s) {
} v; } v;
v.fval = _currentValue; v.fval = _currentValue;
if (nvs_set_i32(_handle, _keyName, v.ival)) { if (nvs_set_i32(_handle, _keyName, v.ival)) {
return STATUS_NVS_SET_FAILED; return Error::NvsSetFailed;
} }
_storedValue = _currentValue; _storedValue = _currentValue;
} }
} }
return STATUS_OK; return Error::Ok;
} }
const char* FloatSetting::getStringValue() { const char* FloatSetting::getStringValue() {
@@ -345,11 +348,12 @@ void StringSetting::setDefault() {
} }
} }
err_t StringSetting::setStringValue(char* s) { Error StringSetting::setStringValue(char* s) {
if (_minLength && _maxLength && (strlen(s) < _minLength || strlen(s) > _maxLength)) { if (_minLength && _maxLength && (strlen(s) < _minLength || strlen(s) > _maxLength)) {
return STATUS_BAD_NUMBER_FORMAT; return Error::BadNumberFormat;
} }
if (err_t err = check(s)) { Error err = check(s);
if (err != Error::Ok) {
return err; return err;
} }
_currentValue = s; _currentValue = s;
@@ -359,12 +363,12 @@ err_t StringSetting::setStringValue(char* s) {
_storedValue = _defaultValue; _storedValue = _defaultValue;
} else { } else {
if (nvs_set_str(_handle, _keyName, _currentValue.c_str())) { if (nvs_set_str(_handle, _keyName, _currentValue.c_str())) {
return STATUS_NVS_SET_FAILED; return Error::NvsSetFailed;
} }
_storedValue = _currentValue; _storedValue = _currentValue;
} }
} }
return STATUS_OK; return Error::Ok;
} }
const char* StringSetting::getStringValue() { const char* StringSetting::getStringValue() {
@@ -418,7 +422,7 @@ void EnumSetting::setDefault() {
// either with the string name or the numeric value. // either with the string name or the numeric value.
// This is necessary for WebUI, which uses the number // This is necessary for WebUI, which uses the number
// for setting. // for setting.
err_t EnumSetting::setStringValue(char* s) { Error EnumSetting::setStringValue(char* s) {
s = trim(s); s = trim(s);
enum_opt_t::iterator it = _options->find(s); enum_opt_t::iterator it = _options->find(s);
if (it == _options->end()) { if (it == _options->end()) {
@@ -426,13 +430,13 @@ err_t EnumSetting::setStringValue(char* s) {
// Disallow empty string // Disallow empty string
if (!s || !*s) { if (!s || !*s) {
return STATUS_BAD_NUMBER_FORMAT; return Error::BadNumberFormat;
} }
char* endptr; char* endptr;
uint8_t num = strtol(s, &endptr, 10); uint8_t num = strtol(s, &endptr, 10);
// Disallow non-numeric characters in string // Disallow non-numeric characters in string
if (*endptr) { if (*endptr) {
return STATUS_BAD_NUMBER_FORMAT; return Error::BadNumberFormat;
} }
for (it = _options->begin(); it != _options->end(); it++) { for (it = _options->begin(); it != _options->end(); it++) {
if (it->second == num) { if (it->second == num) {
@@ -440,7 +444,7 @@ err_t EnumSetting::setStringValue(char* s) {
} }
} }
if (it == _options->end()) { if (it == _options->end()) {
return STATUS_BAD_NUMBER_FORMAT; return Error::BadNumberFormat;
} }
} }
_currentValue = it->second; _currentValue = it->second;
@@ -449,12 +453,12 @@ err_t EnumSetting::setStringValue(char* s) {
nvs_erase_key(_handle, _keyName); nvs_erase_key(_handle, _keyName);
} else { } else {
if (nvs_set_i8(_handle, _keyName, _currentValue)) { if (nvs_set_i8(_handle, _keyName, _currentValue)) {
return STATUS_NVS_SET_FAILED; return Error::NvsSetFailed;
} }
_storedValue = _currentValue; _storedValue = _currentValue;
} }
} }
return STATUS_OK; return Error::Ok;
} }
const char* EnumSetting::getStringValue() { const char* EnumSetting::getStringValue() {
@@ -507,7 +511,7 @@ void FlagSetting::setDefault() {
} }
} }
err_t FlagSetting::setStringValue(char* s) { Error FlagSetting::setStringValue(char* s) {
s = trim(s); s = trim(s);
_currentValue = (strcasecmp(s, "on") == 0) || (strcasecmp(s, "true") == 0) || (strcasecmp(s, "enabled") == 0) || _currentValue = (strcasecmp(s, "on") == 0) || (strcasecmp(s, "true") == 0) || (strcasecmp(s, "enabled") == 0) ||
(strcasecmp(s, "yes") == 0) || (strcasecmp(s, "1") == 0); (strcasecmp(s, "yes") == 0) || (strcasecmp(s, "1") == 0);
@@ -518,12 +522,12 @@ err_t FlagSetting::setStringValue(char* s) {
nvs_erase_key(_handle, _keyName); nvs_erase_key(_handle, _keyName);
} else { } else {
if (nvs_set_i8(_handle, _keyName, _currentValue)) { if (nvs_set_i8(_handle, _keyName, _currentValue)) {
return STATUS_NVS_SET_FAILED; return Error::NvsSetFailed;
} }
_storedValue = _currentValue; _storedValue = _currentValue;
} }
} }
return STATUS_OK; return Error::Ok;
} }
const char* FlagSetting::getStringValue() { const char* FlagSetting::getStringValue() {
return get() ? "On" : "Off"; return get() ? "On" : "Off";
@@ -579,14 +583,15 @@ void IPaddrSetting::setDefault() {
} }
} }
err_t IPaddrSetting::setStringValue(char* s) { Error IPaddrSetting::setStringValue(char* s) {
s = trim(s); s = trim(s);
if (err_t err = check(s)) { Error err = check(s);
if (err != Error::Ok) {
return err; return err;
} }
IPAddress ipaddr; IPAddress ipaddr;
if (!ipaddr.fromString(s)) { if (!ipaddr.fromString(s)) {
return STATUS_INVALID_VALUE; return Error::InvalidValue;
} }
_currentValue = ipaddr; _currentValue = ipaddr;
if (_storedValue != _currentValue) { if (_storedValue != _currentValue) {
@@ -594,12 +599,12 @@ err_t IPaddrSetting::setStringValue(char* s) {
nvs_erase_key(_handle, _keyName); nvs_erase_key(_handle, _keyName);
} else { } else {
if (nvs_set_i32(_handle, _keyName, (int32_t)_currentValue)) { if (nvs_set_i32(_handle, _keyName, (int32_t)_currentValue)) {
return STATUS_NVS_SET_FAILED; return Error::NvsSetFailed;
} }
_storedValue = _currentValue; _storedValue = _currentValue;
} }
} }
return STATUS_OK; return Error::Ok;
} }
const char* IPaddrSetting::getStringValue() { const char* IPaddrSetting::getStringValue() {
@@ -618,9 +623,9 @@ void IPaddrSetting::addWebui(WebUI::JSONencoder* j) {
AxisSettings::AxisSettings(const char* axisName) : name(axisName) {} AxisSettings::AxisSettings(const char* axisName) : name(axisName) {}
err_t GrblCommand::action(char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error GrblCommand::action(char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
if (sys.state & _disallowedStates) { if (sys.state & _disallowedStates) {
return STATUS_IDLE_ERROR; return Error::IdleError;
} }
return _action((const char*)value, auth_level, out); return _action((const char*)value, auth_level, out);
}; };

View File

@@ -68,7 +68,7 @@ public:
// Derived classes may override it to do something. // Derived classes may override it to do something.
virtual void addWebui(WebUI::JSONencoder*) {}; virtual void addWebui(WebUI::JSONencoder*) {};
virtual err_t action(char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) = 0; virtual Error action(char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) = 0;
}; };
class Setting : public Word { class Setting : public Word {
@@ -87,12 +87,12 @@ public:
static Setting* List; static Setting* List;
Setting* next() { return link; } Setting* next() { return link; }
err_t check(char* s); Error check(char* s);
static err_t report_nvs_stats(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { static Error report_nvs_stats(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
nvs_stats_t stats; nvs_stats_t stats;
if (err_t err = nvs_get_stats(NULL, &stats)) { if (esp_err_t err = nvs_get_stats(NULL, &stats)) {
return err; return Error::NvsGetStatsFailed;
} }
grbl_sendf(out->client(), "[MSG: NVS Used: %d Free: %d Total: %d]\r\n", stats.used_entries, stats.free_entries, stats.total_entries); grbl_sendf(out->client(), "[MSG: NVS Used: %d Free: %d Total: %d]\r\n", stats.used_entries, stats.free_entries, stats.total_entries);
#if 0 // The SDK we use does not have this yet #if 0 // The SDK we use does not have this yet
@@ -104,13 +104,12 @@ public:
grbl_sendf(out->client(), "namespace %s key '%s', type '%d' \n", info.namespace_name, info.key, info.type); grbl_sendf(out->client(), "namespace %s key '%s', type '%d' \n", info.namespace_name, info.key, info.type);
} }
#endif #endif
return STATUS_OK; return Error::Ok;
} }
static err_t eraseNVS(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { static Error eraseNVS(const char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
nvs_erase_all(_handle); nvs_erase_all(_handle);
// return STATUS_OK; return Error::Ok;
return 0;
} }
~Setting() {} ~Setting() {}
@@ -129,8 +128,8 @@ public:
// Derived classes may override it to do something. // Derived classes may override it to do something.
virtual void addWebui(WebUI::JSONencoder*) {}; virtual void addWebui(WebUI::JSONencoder*) {};
virtual err_t setStringValue(char* value) = 0; virtual Error setStringValue(char* value) = 0;
err_t setStringValue(String s) { return setStringValue(s.c_str()); } Error setStringValue(String s) { return setStringValue(s.c_str()); }
virtual const char* getStringValue() = 0; virtual const char* getStringValue() = 0;
virtual const char* getCompatibleValue() { return getStringValue(); } virtual const char* getCompatibleValue() { return getStringValue(); }
}; };
@@ -167,7 +166,7 @@ public:
void load(); void load();
void setDefault(); void setDefault();
void addWebui(WebUI::JSONencoder*); void addWebui(WebUI::JSONencoder*);
err_t setStringValue(char* value); Error setStringValue(char* value);
const char* getStringValue(); const char* getStringValue();
int32_t get() { return _currentValue; } int32_t get() { return _currentValue; }
@@ -195,7 +194,7 @@ public:
void load(); void load();
void setDefault(); void setDefault();
void addWebui(WebUI::JSONencoder*); void addWebui(WebUI::JSONencoder*);
err_t setStringValue(char* value); Error setStringValue(char* value);
const char* getCompatibleValue(); const char* getCompatibleValue();
const char* getStringValue(); const char* getStringValue();
@@ -235,7 +234,7 @@ public:
void setDefault(); void setDefault();
// There are no Float settings in WebUI // There are no Float settings in WebUI
void addWebui(WebUI::JSONencoder*) {} void addWebui(WebUI::JSONencoder*) {}
err_t setStringValue(char* value); Error setStringValue(char* value);
const char* getStringValue(); const char* getStringValue();
float get() { return _currentValue; } float get() { return _currentValue; }
@@ -269,7 +268,7 @@ public:
void load(); void load();
void setDefault(); void setDefault();
void addWebui(WebUI::JSONencoder*); void addWebui(WebUI::JSONencoder*);
err_t setStringValue(char* value); Error setStringValue(char* value);
const char* getStringValue(); const char* getStringValue();
const char* get() { return _currentValue.c_str(); } const char* get() { return _currentValue.c_str(); }
@@ -301,7 +300,7 @@ public:
void load(); void load();
void setDefault(); void setDefault();
void addWebui(WebUI::JSONencoder*); void addWebui(WebUI::JSONencoder*);
err_t setStringValue(char* value); Error setStringValue(char* value);
const char* getStringValue(); const char* getStringValue();
int8_t get() { return _currentValue; } int8_t get() { return _currentValue; }
@@ -329,7 +328,7 @@ public:
// There are no Flag settings in WebUI // There are no Flag settings in WebUI
// The booleans are expressed as Enums // The booleans are expressed as Enums
void addWebui(WebUI::JSONencoder*) {} void addWebui(WebUI::JSONencoder*) {}
err_t setStringValue(char* value); Error setStringValue(char* value);
const char* getCompatibleValue(); const char* getCompatibleValue();
const char* getStringValue(); const char* getStringValue();
@@ -361,7 +360,7 @@ public:
void load(); void load();
void setDefault(); void setDefault();
void addWebui(WebUI::JSONencoder*); void addWebui(WebUI::JSONencoder*);
err_t setStringValue(char* value); Error setStringValue(char* value);
const char* getStringValue(); const char* getStringValue();
uint32_t get() { return _currentValue; } uint32_t get() { return _currentValue; }
@@ -384,7 +383,7 @@ public:
}; };
class WebCommand : public Command { class WebCommand : public Command {
private: private:
err_t (*_action)(char*, WebUI::AuthenticationLevel); Error (*_action)(char*, WebUI::AuthenticationLevel);
const char* password; const char* password;
public: public:
@@ -393,10 +392,10 @@ public:
permissions_t permissions, permissions_t permissions,
const char* grblName, const char* grblName,
const char* name, const char* name,
err_t (*action)(char*, WebUI::AuthenticationLevel)) : Error (*action)(char*, WebUI::AuthenticationLevel)) :
Command(description, type, permissions, grblName, name), Command(description, type, permissions, grblName, name),
_action(action) {} _action(action) {}
err_t action(char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* response); Error action(char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* response);
}; };
enum : uint8_t { enum : uint8_t {
@@ -408,13 +407,13 @@ enum : uint8_t {
class GrblCommand : public Command { class GrblCommand : public Command {
private: private:
err_t (*_action)(const char*, WebUI::AuthenticationLevel, WebUI::ESPResponseStream*); Error (*_action)(const char*, WebUI::AuthenticationLevel, WebUI::ESPResponseStream*);
uint8_t _disallowedStates; uint8_t _disallowedStates;
public: public:
GrblCommand(const char* grblName, GrblCommand(const char* grblName,
const char* name, const char* name,
err_t (*action)(const char*, WebUI::AuthenticationLevel, WebUI::ESPResponseStream*), Error (*action)(const char*, WebUI::AuthenticationLevel, WebUI::ESPResponseStream*),
uint8_t disallowedStates, uint8_t disallowedStates,
permissions_t auth) : permissions_t auth) :
Command(NULL, GRBLCMD, auth, grblName, name), Command(NULL, GRBLCMD, auth, grblName, name),
@@ -422,8 +421,8 @@ public:
GrblCommand(const char* grblName, GrblCommand(const char* grblName,
const char* name, const char* name,
err_t (*action)(const char*, WebUI::AuthenticationLevel, WebUI::ESPResponseStream*), Error (*action)(const char*, WebUI::AuthenticationLevel, WebUI::ESPResponseStream*),
uint8_t disallowedStates) : uint8_t disallowedStates) :
GrblCommand(grblName, name, action, disallowedStates, WG) {} GrblCommand(grblName, name, action, disallowedStates, WG) {}
err_t action(char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* response); Error action(char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* response);
}; };

View File

@@ -162,9 +162,9 @@ static const char* makename(const char* axisName, const char* tail) {
static bool checkStartupLine(char* value) { static bool checkStartupLine(char* value) {
if (sys.state != STATE_IDLE) { if (sys.state != STATE_IDLE) {
return STATUS_IDLE_ERROR; return false;
} }
return gc_execute_line(value, CLIENT_SERIAL) == 0; return gc_execute_line(value, CLIENT_SERIAL) == Error::Ok;
} }
static bool checkStallguard(char* value) { static bool checkStallguard(char* value) {

View File

@@ -186,10 +186,10 @@ void system_clear_exec_accessory_overrides();
// Execute the startup script lines stored in EEPROM upon initialization // Execute the startup script lines stored in EEPROM upon initialization
void system_execute_startup(char* line); void system_execute_startup(char* line);
uint8_t execute_line(char* line, uint8_t client, WebUI::AuthenticationLevel auth_level); Error execute_line(char* line, uint8_t client, WebUI::AuthenticationLevel auth_level);
uint8_t system_execute_line(char* line, WebUI::ESPResponseStream*, WebUI::AuthenticationLevel); Error system_execute_line(char* line, WebUI::ESPResponseStream*, WebUI::AuthenticationLevel);
uint8_t system_execute_line(char* line, uint8_t client, WebUI::AuthenticationLevel); Error system_execute_line(char* line, uint8_t client, WebUI::AuthenticationLevel);
uint8_t do_command_or_setting(const char* key, char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream*); Error do_command_or_setting(const char* key, char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream*);
void system_flag_wco_change(); void system_flag_wco_change();
// Returns machine position of axis 'idx'. Must be sent a 'step' array. // Returns machine position of axis 'idx'. Must be sent a 'step' array.

View File

@@ -115,7 +115,7 @@ namespace WebUI {
_btname = bt_name->get(); _btname = bt_name->get();
if (wifi_radio_mode->get() == ESP_BT) { if (wifi_radio_mode->get() == ESP_BT) {
if (!SerialBT.begin(_btname)) { if (!SerialBT.begin(_btname)) {
report_status_message(STATUS_BT_FAIL_BEGIN, CLIENT_ALL); report_status_message(Error::BtFailBegin, CLIENT_ALL);
} else { } else {
SerialBT.register_callback(&my_spp_cb); SerialBT.register_callback(&my_spp_cb);
grbl_sendf(CLIENT_ALL, "[MSG:BT Started with %s]\r\n", _btname.c_str()); grbl_sendf(CLIENT_ALL, "[MSG:BT Started with %s]\r\n", _btname.c_str());

View File

@@ -486,9 +486,9 @@ namespace WebUI {
char line[256]; char line[256];
strncpy(line, cmd.c_str(), 255); strncpy(line, cmd.c_str(), 255);
ESPResponseStream* espresponse = silent ? NULL : new ESPResponseStream(_webserver); ESPResponseStream* espresponse = silent ? NULL : new ESPResponseStream(_webserver);
err_t err = system_execute_line(line, espresponse, auth_level); Error err = system_execute_line(line, espresponse, auth_level);
String answer; String answer;
if (err == STATUS_OK) { if (err == Error::Ok) {
answer = "ok"; answer = "ok";
} else { } else {
const char* msg = errorString(err); const char* msg = errorString(err);
@@ -496,11 +496,11 @@ namespace WebUI {
if (msg) { if (msg) {
answer += msg; answer += msg;
} else { } else {
answer += err; answer += static_cast<int>(err);
} }
} }
if (silent || !espresponse->anyOutput()) { if (silent || !espresponse->anyOutput()) {
_webserver->send(err ? 401 : 200, "text/plain", answer); _webserver->send(err != Error::Ok ? 401 : 200, "text/plain", answer);
} else { } else {
espresponse->flush(); espresponse->flush();
} }
@@ -615,14 +615,14 @@ namespace WebUI {
newpassword.toCharArray(pwdbuf, MAX_LOCAL_PASSWORD_LENGTH + 1); newpassword.toCharArray(pwdbuf, MAX_LOCAL_PASSWORD_LENGTH + 1);
if (COMMANDS::isLocalPasswordValid(pwdbuf)) { if (COMMANDS::isLocalPasswordValid(pwdbuf)) {
err_t err; Error err;
if (sUser == DEFAULT_ADMIN_LOGIN) { if (sUser == DEFAULT_ADMIN_LOGIN) {
err = admin_password->setStringValue(pwdbuf); err = admin_password->setStringValue(pwdbuf);
} else { } else {
err = user_password->setStringValue(pwdbuf); err = user_password->setStringValue(pwdbuf);
} }
if (err) { if (err != Error::Ok) {
msg_alert_error = true; msg_alert_error = true;
smsg = "Error: Cannot apply changes"; smsg = "Error: Cannot apply changes";
code = 500; code = 500;

View File

@@ -162,7 +162,7 @@ namespace WebUI {
} }
} }
err_t WebCommand::action(char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) { Error WebCommand::action(char* value, WebUI::AuthenticationLevel auth_level, WebUI::ESPResponseStream* out) {
char empty = '\0'; char empty = '\0';
if (!value) { if (!value) {
value = &empty; value = &empty;
@@ -223,7 +223,7 @@ namespace WebUI {
webPrintln(")"); webPrintln(")");
} }
static err_t showFwInfo(char* parameter, AuthenticationLevel auth_level) { // ESP800 static Error showFwInfo(char* parameter, AuthenticationLevel auth_level) { // ESP800
webPrint("FW version:" GRBL_VERSION " (" GRBL_VERSION_BUILD ")" webPrint("FW version:" GRBL_VERSION " (" GRBL_VERSION_BUILD ")"
" # FW target:grbl-embedded # FW HW:"); " # FW target:grbl-embedded # FW HW:");
#ifdef ENABLE_SD_CARD #ifdef ENABLE_SD_CARD
@@ -255,43 +255,43 @@ namespace WebUI {
#endif #endif
//to save time in decoding `?` //to save time in decoding `?`
webPrintln(" # axis:", String(N_AXIS)); webPrintln(" # axis:", String(N_AXIS));
return STATUS_OK; return Error::Ok;
} }
static err_t SPIFFSSize(char* parameter, AuthenticationLevel auth_level) { // ESP720 static Error SPIFFSSize(char* parameter, AuthenticationLevel auth_level) { // ESP720
webPrint(parameter); webPrint(parameter);
webPrint("SPIFFS Total:", ESPResponseStream::formatBytes(SPIFFS.totalBytes())); webPrint("SPIFFS Total:", ESPResponseStream::formatBytes(SPIFFS.totalBytes()));
webPrintln(" Used:", ESPResponseStream::formatBytes(SPIFFS.usedBytes())); webPrintln(" Used:", ESPResponseStream::formatBytes(SPIFFS.usedBytes()));
return STATUS_OK; return Error::Ok;
} }
static err_t formatSpiffs(char* parameter, AuthenticationLevel auth_level) { // ESP710 static Error formatSpiffs(char* parameter, AuthenticationLevel auth_level) { // ESP710
if (strcmp(parameter, "FORMAT") != 0) { if (strcmp(parameter, "FORMAT") != 0) {
webPrintln("Parameter must be FORMAT"); webPrintln("Parameter must be FORMAT");
return STATUS_INVALID_VALUE; return Error::InvalidValue;
} }
webPrint("Formatting"); webPrint("Formatting");
SPIFFS.format(); SPIFFS.format();
webPrintln("...Done"); webPrintln("...Done");
return STATUS_OK; return Error::Ok;
} }
static err_t runFile(char* parameter, AuthenticationLevel auth_level) { // ESP700 static Error runFile(char* parameter, AuthenticationLevel auth_level) { // ESP700
String path = trim(parameter); String path = trim(parameter);
if ((path.length() > 0) && (path[0] != '/')) { if ((path.length() > 0) && (path[0] != '/')) {
path = "/" + path; path = "/" + path;
} }
if (!SPIFFS.exists(path)) { if (!SPIFFS.exists(path)) {
webPrintln("Error: No such file!"); webPrintln("Error: No such file!");
return STATUS_SD_FILE_NOT_FOUND; return Error::SdFileNotFound;
} }
File currentfile = SPIFFS.open(path, FILE_READ); File currentfile = SPIFFS.open(path, FILE_READ);
if (!currentfile) { //if file open success if (!currentfile) { //if file open success
return STATUS_SD_FAILED_OPEN_FILE; return Error::SdFailedOpenFile;
} }
//until no line in file //until no line in file
err_t err; Error err;
err_t accumErr = STATUS_OK; Error accumErr = Error::Ok;
while (currentfile.available()) { while (currentfile.available()) {
String currentline = currentfile.readStringUntil('\n'); String currentline = currentfile.readStringUntil('\n');
if (currentline.length() > 0) { if (currentline.length() > 0) {
@@ -300,7 +300,7 @@ namespace WebUI {
// TODO Settings - feed into command interpreter // TODO Settings - feed into command interpreter
// while accumulating error codes // while accumulating error codes
err = execute_line((char*)line, CLIENT_WEBUI, auth_level); err = execute_line((char*)line, CLIENT_WEBUI, auth_level);
if (err != STATUS_OK) { if (err != Error::Ok) {
accumErr = err; accumErr = err;
} }
COMMANDS::wait(1); COMMANDS::wait(1);
@@ -311,71 +311,71 @@ namespace WebUI {
} }
#ifdef ENABLE_NOTIFICATIONS #ifdef ENABLE_NOTIFICATIONS
static err_t showSetNotification(char* parameter, AuthenticationLevel auth_level) { // ESP610 static Error showSetNotification(char* parameter, AuthenticationLevel auth_level) { // ESP610
if (*parameter == '\0') { if (*parameter == '\0') {
webPrint("", notification_type->getStringValue()); webPrint("", notification_type->getStringValue());
webPrintln(" ", notification_ts->getStringValue()); webPrintln(" ", notification_ts->getStringValue());
return STATUS_OK; return Error::Ok;
} }
if (!split_params(parameter)) { if (!split_params(parameter)) {
return STATUS_INVALID_VALUE; return Error::InvalidValue;
} }
char* ts = get_param("TS", false); char* ts = get_param("TS", false);
char* t2 = get_param("T2", false); char* t2 = get_param("T2", false);
char* t1 = get_param("T1", false); char* t1 = get_param("T1", false);
char* ty = get_param("type", false); char* ty = get_param("type", false);
err_t err = notification_type->setStringValue(ty); Error err = notification_type->setStringValue(ty);
if (!err) { if (err == Error::Ok) {
err = notification_t1->setStringValue(t1); err = notification_t1->setStringValue(t1);
} }
if (!err) { if (err == Error::Ok) {
err = notification_t2->setStringValue(t2); err = notification_t2->setStringValue(t2);
} }
if (!err) { if (err == Error::Ok) {
err = notification_ts->setStringValue(ts); err = notification_ts->setStringValue(ts);
} }
return err; return err;
} }
static err_t sendMessage(char* parameter, AuthenticationLevel auth_level) { // ESP600 static Error sendMessage(char* parameter, AuthenticationLevel auth_level) { // ESP600
if (*parameter == '\0') { if (*parameter == '\0') {
webPrintln("Invalid message!"); webPrintln("Invalid message!");
return STATUS_INVALID_VALUE; return Error::InvalidValue;
} }
if (!notificationsservice.sendMSG("GRBL Notification", parameter)) { if (!notificationsservice.sendMSG("GRBL Notification", parameter)) {
webPrintln("Cannot send message!"); webPrintln("Cannot send message!");
return STATUS_MESSAGE_FAILED; return Error::MessageFailed;
} }
return STATUS_OK; return Error::Ok;
} }
#endif #endif
#ifdef ENABLE_AUTHENTICATION #ifdef ENABLE_AUTHENTICATION
static err_t setUserPassword(char* parameter, AuthenticationLevel auth_level) { // ESP555 static Error setUserPassword(char* parameter, AuthenticationLevel auth_level) { // ESP555
if (*parameter == '\0') { if (*parameter == '\0') {
user_password->setDefault(); user_password->setDefault();
return STATUS_OK; return Error::Ok;
} }
if (user_password->setStringValue(parameter)) { if (user_password->setStringValue(parameter)) {
webPrintln("Invalid Password"); webPrintln("Invalid Password");
return STATUS_INVALID_VALUE; return Error::InvalidValue;
} }
return STATUS_OK; return Error::Ok;
} }
#endif #endif
static err_t setSystemMode(char* parameter, AuthenticationLevel auth_level) { // ESP444 static Error setSystemMode(char* parameter, AuthenticationLevel auth_level) { // ESP444
parameter = trim(parameter); parameter = trim(parameter);
if (strcasecmp(parameter, "RESTART") != 0) { if (strcasecmp(parameter, "RESTART") != 0) {
webPrintln("Incorrect command"); webPrintln("Incorrect command");
return STATUS_INVALID_VALUE; return Error::InvalidValue;
} }
grbl_send(CLIENT_ALL, "[MSG:Restart ongoing]\r\n"); grbl_send(CLIENT_ALL, "[MSG:Restart ongoing]\r\n");
COMMANDS::restart_ESP(); COMMANDS::restart_ESP();
return STATUS_OK; return Error::Ok;
} }
static err_t showSysStats(char* parameter, AuthenticationLevel auth_level) { // ESP420 static Error showSysStats(char* parameter, AuthenticationLevel auth_level) { // ESP420
webPrintln("Chip ID: ", String((uint16_t)(ESP.getEfuseMac() >> 32))); webPrintln("Chip ID: ", String((uint16_t)(ESP.getEfuseMac() >> 32)));
webPrintln("CPU Frequency: ", String(ESP.getCpuFreqMHz()) + "Mhz"); webPrintln("CPU Frequency: ", String(ESP.getCpuFreqMHz()) + "Mhz");
webPrintln("CPU Temperature: ", String(temperatureRead(), 1) + "C"); webPrintln("CPU Temperature: ", String(temperatureRead(), 1) + "C");
@@ -537,11 +537,11 @@ namespace WebUI {
webPrint(GRBL_VERSION_BUILD); webPrint(GRBL_VERSION_BUILD);
webPrint(") (ESP32)"); webPrint(") (ESP32)");
webPrintln(""); webPrintln("");
return STATUS_OK; return Error::Ok;
} }
#ifdef ENABLE_WIFI #ifdef ENABLE_WIFI
static err_t listAPs(char* parameter, AuthenticationLevel auth_level) { // ESP410 static Error listAPs(char* parameter, AuthenticationLevel auth_level) { // ESP410
JSONencoder* j = new JSONencoder(espresponse->client() != CLIENT_WEBUI); JSONencoder* j = new JSONencoder(espresponse->client() != CLIENT_WEBUI);
j->begin(); j->begin();
j->begin_array("AP_LIST"); j->begin_array("AP_LIST");
@@ -578,27 +578,27 @@ namespace WebUI {
if (espresponse->client() != CLIENT_WEBUI) { if (espresponse->client() != CLIENT_WEBUI) {
espresponse->println(""); espresponse->println("");
} }
return STATUS_OK; return Error::Ok;
} }
#endif #endif
static err_t setWebSetting(char* parameter, AuthenticationLevel auth_level) { // ESP401 static Error setWebSetting(char* parameter, AuthenticationLevel auth_level) { // ESP401
// We do not need the "T=" (type) parameter because the // We do not need the "T=" (type) parameter because the
// Setting objects know their own type // Setting objects know their own type
if (!split_params(parameter)) { if (!split_params(parameter)) {
return STATUS_INVALID_VALUE; return Error::InvalidValue;
} }
char* sval = get_param("V", true); char* sval = get_param("V", true);
const char* spos = get_param("P", false); const char* spos = get_param("P", false);
if (*spos == '\0') { if (*spos == '\0') {
webPrintln("Missing parameter"); webPrintln("Missing parameter");
return STATUS_INVALID_VALUE; return Error::InvalidValue;
} }
err_t ret = do_command_or_setting(spos, sval, auth_level, espresponse); Error ret = do_command_or_setting(spos, sval, auth_level, espresponse);
return ret; return ret;
} }
static err_t listSettings(char* parameter, AuthenticationLevel auth_level) { // ESP400 static Error listSettings(char* parameter, AuthenticationLevel auth_level) { // ESP400
JSONencoder* j = new JSONencoder(espresponse->client() != CLIENT_WEBUI); JSONencoder* j = new JSONencoder(espresponse->client() != CLIENT_WEBUI);
j->begin(); j->begin();
j->begin_array("EEPROM"); j->begin_array("EEPROM");
@@ -610,60 +610,60 @@ namespace WebUI {
j->end_array(); j->end_array();
webPrint(j->end()); webPrint(j->end());
delete j; delete j;
return STATUS_OK; return Error::Ok;
} }
#ifdef ENABLE_SD_CARD #ifdef ENABLE_SD_CARD
static err_t runSDFile(char* parameter, AuthenticationLevel auth_level) { // ESP220 static Error runSDFile(char* parameter, AuthenticationLevel auth_level) { // ESP220
parameter = trim(parameter); parameter = trim(parameter);
if (*parameter == '\0') { if (*parameter == '\0') {
webPrintln("Missing file name!"); webPrintln("Missing file name!");
return STATUS_INVALID_VALUE; return Error::InvalidValue;
} }
int8_t state = get_sd_state(true); int8_t state = get_sd_state(true);
if (state != SDCARD_IDLE) { if (state != SDCARD_IDLE) {
if (state == SDCARD_NOT_PRESENT) { if (state == SDCARD_NOT_PRESENT) {
webPrintln("No SD Card"); webPrintln("No SD Card");
return STATUS_SD_FAILED_MOUNT; return Error::SdFailedMount;
} else { } else {
webPrintln("SD Card Busy"); webPrintln("SD Card Busy");
return STATUS_SD_FAILED_BUSY; return Error::SdFailedBusy;
} }
} }
if (sys.state != STATE_IDLE) { if (sys.state != STATE_IDLE) {
webPrintln("Busy"); webPrintln("Busy");
return STATUS_IDLE_ERROR; return Error::IdleError;
} }
if (!openFile(SD, parameter)) { if (!openFile(SD, parameter)) {
report_status_message(STATUS_SD_FAILED_READ, (espresponse) ? espresponse->client() : CLIENT_ALL); report_status_message(Error::SdFailedRead, (espresponse) ? espresponse->client() : CLIENT_ALL);
webPrintln(""); webPrintln("");
return STATUS_OK; return Error::Ok;
} }
char fileLine[255]; char fileLine[255];
if (!readFileLine(fileLine, 255)) { if (!readFileLine(fileLine, 255)) {
//No need notification here it is just a macro //No need notification here it is just a macro
closeFile(); closeFile();
webPrintln(""); webPrintln("");
return STATUS_OK; return Error::Ok;
} }
SD_client = (espresponse) ? espresponse->client() : CLIENT_ALL; SD_client = (espresponse) ? espresponse->client() : CLIENT_ALL;
report_status_message(gc_execute_line(fileLine, (espresponse) ? espresponse->client() : CLIENT_ALL), report_status_message(gc_execute_line(fileLine, (espresponse) ? espresponse->client() : CLIENT_ALL),
(espresponse) ? espresponse->client() : CLIENT_ALL); // execute the first line (espresponse) ? espresponse->client() : CLIENT_ALL); // execute the first line
report_realtime_status((espresponse) ? espresponse->client() : CLIENT_ALL); report_realtime_status((espresponse) ? espresponse->client() : CLIENT_ALL);
webPrintln(""); webPrintln("");
return STATUS_OK; return Error::Ok;
} }
static err_t deleteSDObject(char* parameter, AuthenticationLevel auth_level) { // ESP215 static Error deleteSDObject(char* parameter, AuthenticationLevel auth_level) { // ESP215
parameter = trim(parameter); parameter = trim(parameter);
if (*parameter == '\0') { if (*parameter == '\0') {
webPrintln("Missing file name!"); webPrintln("Missing file name!");
return STATUS_INVALID_VALUE; return Error::InvalidValue;
} }
int8_t state = get_sd_state(true); int8_t state = get_sd_state(true);
if (state != SDCARD_IDLE) { if (state != SDCARD_IDLE) {
webPrintln((state == SDCARD_NOT_PRESENT) ? "No SD card" : "Busy"); webPrintln((state == SDCARD_NOT_PRESENT) ? "No SD card" : "Busy");
return STATUS_OK; return Error::Ok;
} }
String path = parameter; String path = parameter;
if (parameter[0] != '/') { if (parameter[0] != '/') {
@@ -672,34 +672,34 @@ namespace WebUI {
File file2del = SD.open(path); File file2del = SD.open(path);
if (!file2del) { if (!file2del) {
webPrintln("Cannot stat file!"); webPrintln("Cannot stat file!");
return STATUS_SD_FILE_NOT_FOUND; return Error::SdFileNotFound;
} }
if (file2del.isDirectory()) { if (file2del.isDirectory()) {
if (!SD.rmdir(path)) { if (!SD.rmdir(path)) {
webPrintln("Cannot delete directory! Is directory empty?"); webPrintln("Cannot delete directory! Is directory empty?");
return STATUS_SD_FAILED_DEL_DIR; return Error::SdFailedDelDir;
} }
webPrintln("Directory deleted."); webPrintln("Directory deleted.");
} else { } else {
if (!SD.remove(path)) { if (!SD.remove(path)) {
webPrintln("Cannot delete file!"); webPrintln("Cannot delete file!");
return STATUS_SD_FAILED_DEL_FILE; return Error::SdFailedDelFile;
} }
webPrintln("File deleted."); webPrintln("File deleted.");
} }
file2del.close(); file2del.close();
return STATUS_OK; return Error::Ok;
} }
static err_t listSDFiles(char* parameter, AuthenticationLevel auth_level) { // ESP210 static Error listSDFiles(char* parameter, AuthenticationLevel auth_level) { // ESP210
int8_t state = get_sd_state(true); int8_t state = get_sd_state(true);
if (state != SDCARD_IDLE) { if (state != SDCARD_IDLE) {
if (state == SDCARD_NOT_PRESENT) { if (state == SDCARD_NOT_PRESENT) {
webPrintln("No SD Card"); webPrintln("No SD Card");
return STATUS_SD_FAILED_MOUNT; return Error::SdFailedMount;
} else { } else {
webPrintln("SD Card Busy"); webPrintln("SD Card Busy");
return STATUS_SD_FAILED_BUSY; return Error::SdFailedBusy;
} }
} }
webPrintln(""); webPrintln("");
@@ -709,11 +709,11 @@ namespace WebUI {
ssd += " Total:" + ESPResponseStream::formatBytes(SD.totalBytes()); ssd += " Total:" + ESPResponseStream::formatBytes(SD.totalBytes());
ssd += "]"; ssd += "]";
webPrintln(ssd); webPrintln(ssd);
return STATUS_OK; return Error::Ok;
} }
#endif #endif
static err_t listLocalFiles(char* parameter, AuthenticationLevel auth_level) { // No ESP command static Error listLocalFiles(char* parameter, AuthenticationLevel auth_level) { // No ESP command
webPrintln(""); webPrintln("");
listDir(SPIFFS, "/", 10, espresponse->client()); listDir(SPIFFS, "/", 10, espresponse->client());
String ssd = "[Local FS Free:" + ESPResponseStream::formatBytes(SPIFFS.totalBytes() - SPIFFS.usedBytes()); String ssd = "[Local FS Free:" + ESPResponseStream::formatBytes(SPIFFS.totalBytes() - SPIFFS.usedBytes());
@@ -721,7 +721,7 @@ namespace WebUI {
ssd += " Total:" + ESPResponseStream::formatBytes(SPIFFS.totalBytes()); ssd += " Total:" + ESPResponseStream::formatBytes(SPIFFS.totalBytes());
ssd += "]"; ssd += "]";
webPrintln(ssd); webPrintln(ssd);
return STATUS_OK; return Error::Ok;
} }
static void listDirJSON(fs::FS& fs, const char* dirname, uint8_t levels, JSONencoder* j) { static void listDirJSON(fs::FS& fs, const char* dirname, uint8_t levels, JSONencoder* j) {
@@ -744,7 +744,7 @@ namespace WebUI {
} }
} }
static err_t listLocalFilesJSON(char* parameter, AuthenticationLevel auth_level) { // No ESP command static Error listLocalFilesJSON(char* parameter, AuthenticationLevel auth_level) { // No ESP command
JSONencoder* j = new JSONencoder(espresponse->client() != CLIENT_WEBUI); JSONencoder* j = new JSONencoder(espresponse->client() != CLIENT_WEBUI);
j->begin(); j->begin();
j->begin_array("files"); j->begin_array("files");
@@ -757,10 +757,10 @@ namespace WebUI {
if (espresponse->client() != CLIENT_WEBUI) { if (espresponse->client() != CLIENT_WEBUI) {
webPrintln(""); webPrintln("");
} }
return STATUS_OK; return Error::Ok;
} }
static err_t showSDStatus(char* parameter, AuthenticationLevel auth_level) { // ESP200 static Error showSDStatus(char* parameter, AuthenticationLevel auth_level) { // ESP200
const char* resp = "No SD card"; const char* resp = "No SD card";
#ifdef ENABLE_SD_CARD #ifdef ENABLE_SD_CARD
switch (get_sd_state(true)) { switch (get_sd_state(true)) {
@@ -770,10 +770,10 @@ namespace WebUI {
} }
#endif #endif
webPrintln(resp); webPrintln(resp);
return STATUS_OK; return Error::Ok;
} }
static err_t setRadioState(char* parameter, AuthenticationLevel auth_level) { // ESP115 static Error setRadioState(char* parameter, AuthenticationLevel auth_level) { // ESP115
parameter = trim(parameter); parameter = trim(parameter);
if (*parameter == '\0') { if (*parameter == '\0') {
// Display the radio state // Display the radio state
@@ -789,7 +789,7 @@ namespace WebUI {
} }
#endif #endif
webPrintln(on ? "ON" : "OFF"); webPrintln(on ? "ON" : "OFF");
return STATUS_OK; return Error::Ok;
} }
int8_t on = -1; int8_t on = -1;
if (strcasecmp(parameter, "ON") == 0) { if (strcasecmp(parameter, "ON") == 0) {
@@ -799,7 +799,7 @@ namespace WebUI {
} }
if (on == -1) { if (on == -1) {
webPrintln("only ON or OFF mode supported!"); webPrintln("only ON or OFF mode supported!");
return STATUS_INVALID_VALUE; return Error::InvalidValue;
} }
//Stop everything //Stop everything
@@ -816,7 +816,7 @@ namespace WebUI {
//if On start proper service //if On start proper service
if (!on) { if (!on) {
webPrintln("[MSG: Radio is Off]"); webPrintln("[MSG: Radio is Off]");
return STATUS_OK; return Error::Ok;
} }
//On //On
#ifdef WIFI_OR_BLUETOOTH #ifdef WIFI_OR_BLUETOOTH
@@ -825,58 +825,58 @@ namespace WebUI {
case ESP_WIFI_STA: case ESP_WIFI_STA:
# if !defined(ENABLE_WIFI) # if !defined(ENABLE_WIFI)
webPrintln("WiFi is not enabled!"); webPrintln("WiFi is not enabled!");
return STATUS_WIFI_FAIL_BEGIN; return Error::WifiFailBegin;
# else # else
wifi_config.begin(); wifi_config.begin();
return STATUS_OK; return Error::Ok;
# endif # endif
case ESP_BT: case ESP_BT:
# if !defined(ENABLE_BLUETOOTH) # if !defined(ENABLE_BLUETOOTH)
webPrintln("Bluetooth is not enabled!"); webPrintln("Bluetooth is not enabled!");
return STATUS_BT_FAIL_BEGIN; return Error::BtFailBegin;
# else # else
bt_config.begin(); bt_config.begin();
return STATUS_OK; return Error::Ok;
# endif # endif
default: webPrintln("[MSG: Radio is Off]"); return STATUS_OK; default: webPrintln("[MSG: Radio is Off]"); return Error::Ok;
} }
#endif #endif
return STATUS_OK; return Error::Ok;
} }
#ifdef ENABLE_WIFI #ifdef ENABLE_WIFI
static err_t showIP(char* parameter, AuthenticationLevel auth_level) { // ESP111 static Error showIP(char* parameter, AuthenticationLevel auth_level) { // ESP111
webPrintln(parameter, WiFi.getMode() == WIFI_STA ? WiFi.localIP() : WiFi.softAPIP()); webPrintln(parameter, WiFi.getMode() == WIFI_STA ? WiFi.localIP() : WiFi.softAPIP());
return STATUS_OK; return Error::Ok;
} }
static err_t showSetStaParams(char* parameter, AuthenticationLevel auth_level) { // ESP103 static Error showSetStaParams(char* parameter, AuthenticationLevel auth_level) { // ESP103
if (*parameter == '\0') { if (*parameter == '\0') {
webPrint("IP:", wifi_sta_ip->getStringValue()); webPrint("IP:", wifi_sta_ip->getStringValue());
webPrint(" GW:", wifi_sta_gateway->getStringValue()); webPrint(" GW:", wifi_sta_gateway->getStringValue());
webPrintln(" MSK:", wifi_sta_netmask->getStringValue()); webPrintln(" MSK:", wifi_sta_netmask->getStringValue());
return STATUS_OK; return Error::Ok;
} }
if (!split_params(parameter)) { if (!split_params(parameter)) {
return STATUS_INVALID_VALUE; return Error::InvalidValue;
} }
char* gateway = get_param("GW", false); char* gateway = get_param("GW", false);
char* netmask = get_param("MSK", false); char* netmask = get_param("MSK", false);
char* ip = get_param("IP", false); char* ip = get_param("IP", false);
err_t err = wifi_sta_ip->setStringValue(ip); Error err = wifi_sta_ip->setStringValue(ip);
if (!err) { if (err == Error::Ok) {
err = wifi_sta_netmask->setStringValue(netmask); err = wifi_sta_netmask->setStringValue(netmask);
} }
if (!err) { if (err == Error::Ok) {
err = wifi_sta_gateway->setStringValue(gateway); err = wifi_sta_gateway->setStringValue(gateway);
} }
return err; return err;
} }
#endif #endif
static err_t showWebHelp(char* parameter, AuthenticationLevel auth_level) { // ESP0 static Error showWebHelp(char* parameter, AuthenticationLevel auth_level) { // ESP0
webPrintln("Persistent web settings - $name to show, $name=value to set"); webPrintln("Persistent web settings - $name to show, $name=value to set");
webPrintln("ESPname FullName Description"); webPrintln("ESPname FullName Description");
webPrintln("------- -------- -----------"); webPrintln("------- -------- -----------");
@@ -910,7 +910,7 @@ namespace WebUI {
} }
} }
} }
return STATUS_OK; return Error::Ok;
} }
// WEB_COMMON should always be defined. It is a trick to make the definitions // WEB_COMMON should always be defined. It is a trick to make the definitions

View File

@@ -10,7 +10,7 @@ Function BuildMachine($names) {
$env:PLATFORMIO_BUILD_FLAGS = "-DMACHINE_FILENAME=$basename" $env:PLATFORMIO_BUILD_FLAGS = "-DMACHINE_FILENAME=$basename"
$displayname = $basename $displayname = $basename
Write-Output "Building machine $displayname" Write-Output "Building machine $displayname"
platformio run 2>&1 | Select-String error,Took platformio run 2>&1 | Select-String Compiling -NotMatch | Select-String error,Took
Write-Output " " Write-Output " "
} }

View File

@@ -10,7 +10,7 @@ trap "echo; exit 255" SIGINT
if [ "$1" = "-v" ]; then if [ "$1" = "-v" ]; then
FILTER="cat" FILTER="cat"
else else
FILTER="grep error\|Took" FILTER="grep -v Compiling | grep error\|Took"
fi fi
set -o pipefail set -o pipefail
NUM_ERRORS=0 NUM_ERRORS=0

View File

@@ -23,7 +23,7 @@ def buildMachine(baseName, verbose=True, extraArgs=None):
app = subprocess.Popen(cmd, env=env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1) app = subprocess.Popen(cmd, env=env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1)
for line in app.stdout: for line in app.stdout:
line = line.decode('utf8') line = line.decode('utf8')
if "Took" in line or 'Uploading' in line or "error" in line.lower(): if "Took" in line or 'Uploading' in line or ("error" in line.lower() and "Compiling" not in line):
print(line, end='') print(line, end='')
app.wait() app.wait()
print() print()