Skip to content

Commit 9368c4b

Browse files
committed
Add output setting support to CLI
1 parent 952d01b commit 9368c4b

File tree

4 files changed

+80
-94
lines changed

4 files changed

+80
-94
lines changed

.circleci/config.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ jobs:
66
steps:
77
- checkout
88
- run: pio upgrade
9-
- run: pio ci --board=esp32dev examples/CLI_Basic/ --lib src/
10-
- run: pio ci --board=esp32dev examples/CLI_Continuous/ --lib src/
9+
- run: pio ci --board=esp32dev examples/CLI/ --lib src/
1110
- run: pio ci --board=esp32dev examples/SerialLogging/ --lib src/
1211
- run: pio ci --board=esp32dev examples/UnitsConversion/ --lib src/
1312
- run: pio ci --board=esp32dev examples/Values/ --lib src/

examples/CLI_Continuous/CLI_Continuous.ino renamed to examples/CLI/CLI.ino

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,25 @@ void setup()
1010
// Setup Serial port
1111
Serial.begin(115200);
1212

13-
// Add Serial as source for CLI
13+
// Add Serial as source and output for CLI
1414
cli.setSource(Serial);
15+
cli.setOutput(Serial);
1516

1617
// Set function to call in case of error
1718
cli.onError([](String error_message){
1819
Serial.println("Error in CLI: " + error_message);
1920
});
2021

2122
// Add commands
22-
cli.addCommand({"help", "Show available commands", [](dream::CommandParams p){
23-
Serial.println("Available commands: ");
23+
cli.addCommand({"help", "Show available commands", [](dream::CommandParams p, Print &output){
24+
output.println("Available commands: ");
2425
for (auto c : cli.getCommands())
2526
{
26-
Serial.println(" - " + c.name + " " + c.info);
27+
output.println(" - " + c.name + " " + c.info);
2728
}
2829
}});
2930

30-
cli.addCommand({"on", "[pin] Set HIGH signal on pin", [](dream::CommandParams p){
31+
cli.addCommand({"on", "[pin] Set HIGH signal on pin", [](dream::CommandParams p, Print &output){
3132
// Get pin from parameters
3233
int pin = p[0].toInt();
3334

@@ -36,11 +37,19 @@ void setup()
3637
digitalWrite(pin, HIGH);
3738
}});
3839

39-
cli.addCommand({"off", "[pin] Set LOW signal on pin", [](dream::CommandParams p){
40+
cli.addCommand({"off", "[pin] Set LOW signal on pin", [](dream::CommandParams p, Print &output){
4041
int pin = p[0].toInt();
4142
pinMode(pin, OUTPUT);
4243
digitalWrite(pin, LOW);
4344
}});
45+
46+
cli.addCommand({"read", "[pin] Read ADC on pin", [](dream::CommandParams p, Print &output){
47+
int pin = p[0].toInt();
48+
pinMode(pin, INPUT);
49+
50+
// Print ADC value
51+
output.println("ADC: " + String(analogRead(pin)) + " on pin " + String(pin));
52+
}});
4453
}
4554

4655
void loop()

examples/CLI_Basic/CLI_Basic.ino

Lines changed: 0 additions & 54 deletions
This file was deleted.

src/debug/cli.h

Lines changed: 64 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ namespace dream
2424
typedef std::vector<String> CommandParams;
2525

2626
// Command function
27-
typedef std::function<void(CommandParams)> CommandFunction;
27+
typedef std::function<void(CommandParams params, Print& output)> CommandFunction;
2828

2929
class CommandLineInterface
3030
{
@@ -44,6 +44,9 @@ namespace dream
4444
// Source for continuous reading
4545
Stream *_source = nullptr;
4646

47+
// Output for command result
48+
Print *_output = nullptr;
49+
4750
// Function to call in case of error
4851
std::function<void(String)> _errorHandler;
4952

@@ -95,21 +98,61 @@ namespace dream
9598
return result;
9699
}
97100

101+
// Run command
102+
void runCommand(String command, Print *output)
103+
{
104+
if (command.isEmpty())
105+
{
106+
_errorHandler("Command is empty");
107+
return;
108+
}
109+
110+
if (output == nullptr)
111+
{
112+
_errorHandler("Output not specified");
113+
return;
114+
}
115+
116+
// Trim string
117+
command.trim();
118+
119+
// Parse command name and arguments
120+
const String name = getFirstArgument(command, ' ');
121+
const std::vector<String> params = splitString(command.substring(name.length()), ' ');
122+
123+
// Find command
124+
for (const Command &c : _commands)
125+
{
126+
if (c.name == name)
127+
{
128+
// Run command
129+
c.run(params, *output);
130+
131+
return;
132+
}
133+
}
134+
135+
// Command wasn't found
136+
_errorHandler("Command " + command + " not found");
137+
return;
138+
}
139+
98140
public: //--------------------------------------------------------------
99141

100-
// Init CLI in basic mode
101-
// In this mode you have to manually cal `run(string)` method.
102-
CommandLineInterface() { }
142+
// Init CLI with default input and output
143+
CommandLineInterface() : _source(&Serial), _output(&Serial) { }
103144

104-
// Init CLI with reading from source
105-
// In this mode you have to place `tick()` method call to your `loop()`
106-
// or you still can use `run(string)` method as well.
107-
CommandLineInterface(Stream *s) : _source(s) { }
108-
CommandLineInterface(Stream &s) : _source(&s) { }
145+
// Init CLI with input and output specified
146+
CommandLineInterface(Stream *source, Print *output) : _source(source), _output(output) { }
147+
CommandLineInterface(Stream &source, Print &output) : _source(&source), _output(&output) { }
109148

110-
// Change mode to reading from source
149+
// Change source
111150
void setSource(Stream *s) { _source = s; }
112151
void setSource(Stream &s) { _source = &s; }
152+
153+
// Change source
154+
void setOutput(Print *s) { _output = s; }
155+
void setOutput(Print &s) { _output = &s; }
113156

114157
// Set function to call in case of error
115158
// Error message will be set as String argument
@@ -144,30 +187,19 @@ namespace dream
144187
// Run command from string
145188
void run(String command)
146189
{
147-
if (command.isEmpty()) return;
148-
149-
// Trim string
150-
command.trim();
151-
152-
// Parse command name and arguments
153-
const String name = getFirstArgument(command, ' ');
154-
const std::vector<String> params = splitString(command.substring(name.length()), ' ');
190+
runCommand(command, _output);
191+
}
155192

156-
// Find command
157-
for (const Command &c : _commands)
158-
{
159-
if (c.name == name)
160-
{
161-
// Run command
162-
c.run(params);
193+
// Run command from string with separate output
194+
void run(String command, Print &output)
195+
{
196+
runCommand(command, &output);
197+
}
163198

164-
return;
165-
}
166-
}
167-
168-
// Command wasn't found
169-
_errorHandler("[CLI] Command " + command + " not found");
170-
return;
199+
// Run command from string with separate output
200+
void run(String command, Print *output)
201+
{
202+
runCommand(command, output);
171203
}
172204
};
173205
}

0 commit comments

Comments
 (0)