Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
co2ampel
ampel-firmware
Commits
06467a3d
Commit
06467a3d
authored
May 05, 2021
by
Eric Duminil
Browse files
Merge branch 'refactor/console' into develop
parents
ab3e5689
7b2385e5
Pipeline
#3589
passed with stage
in 1 minute and 48 seconds
Changes
10
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
ampel-firmware/co2_sensor.cpp
View file @
06467a3d
...
...
@@ -103,15 +103,14 @@ namespace sensor {
Serial
.
println
(
F
(
" s during acclimatization."
));
scd30
.
setMeasurementInterval
(
config
::
measurement_timestep_bootup
);
// [s]
sensor_console
::
defineIntCommand
(
"co2"
,
setCO2forDebugging
,
F
(
"
1500 (Sets co2 level, for debugging purposes)"
));
sensor_console
::
defineIntCommand
(
"timer"
,
setTimer
,
F
(
"
30 (Sets measurement interval, in s)"
));
sensor_console
::
defineCommand
(
"calibrate"
,
startCalibrationProcess
,
F
(
"
(Starts calibration process)"
));
sensor_console
::
defineIntCommand
(
"co2"
,
setCO2forDebugging
,
F
(
"1500 (Sets co2 level, for debugging purposes)"
));
sensor_console
::
defineIntCommand
(
"timer"
,
setTimer
,
F
(
"30 (Sets measurement interval, in s)"
));
sensor_console
::
defineCommand
(
"calibrate"
,
startCalibrationProcess
,
F
(
"(Starts calibration process)"
));
sensor_console
::
defineIntCommand
(
"calibrate"
,
calibrateSensorToSpecificPPM
,
F
(
"
600 (Starts calibration process, to given ppm)"
));
F
(
"600 (Starts calibration process, to given ppm)"
));
sensor_console
::
defineIntCommand
(
"calibrate!"
,
calibrateSensorRightNow
,
F
(
" 600 (Calibrates right now, to given ppm)"
));
sensor_console
::
defineIntCommand
(
"auto_calibrate"
,
setAutoCalibration
,
F
(
" 0/1 (Disables/enables autocalibration)"
));
F
(
"600 (Calibrates right now, to given ppm)"
));
sensor_console
::
defineIntCommand
(
"auto_calibrate"
,
setAutoCalibration
,
F
(
"0/1 (Disables/enables autocalibration)"
));
}
bool
hasSensorSettled
()
{
...
...
ampel-firmware/csv_writer.cpp
View file @
06467a3d
...
...
@@ -118,9 +118,9 @@ namespace csv_writer {
showFilesystemContent
();
Serial
.
println
();
sensor_console
::
defineIntCommand
(
"csv"
,
setCSVinterval
,
F
(
"
60 (Sets CSV writing interval, in s)"
));
sensor_console
::
defineCommand
(
"format_filesystem"
,
formatFilesystem
,
F
(
"
(Deletes the whole filesystem)"
));
sensor_console
::
defineCommand
(
"show_csv"
,
showCSVContent
,
F
(
"
(Displays the complete CSV file on Serial)"
));
sensor_console
::
defineIntCommand
(
"csv"
,
setCSVinterval
,
F
(
"60 (Sets CSV writing interval, in s)"
));
sensor_console
::
defineCommand
(
"format_filesystem"
,
formatFilesystem
,
F
(
"(Deletes the whole filesystem)"
));
sensor_console
::
defineCommand
(
"show_csv"
,
showCSVContent
,
F
(
"(Displays the complete CSV file on Serial)"
));
}
File
openOrCreate
()
{
...
...
ampel-firmware/led_effects.cpp
View file @
06467a3d
...
...
@@ -70,11 +70,19 @@ namespace led_effects {
onBoardLEDOff
();
}
void
showColor
(
int32_t
color
)
{
config
::
night_mode
=
true
;
// In order to avoid overwriting the desired color next time CO2 is displayed
pixels
.
setBrightness
(
255
);
pixels
.
fill
(
color
);
pixels
.
show
();
}
void
setupRing
()
{
pixels
.
begin
();
pixels
.
setBrightness
(
config
::
max_brightness
);
LEDsOff
();
sensor_console
::
defineCommand
(
"night_mode"
,
toggleNightMode
,
F
(
" (Toggles night mode on/off)"
));
sensor_console
::
defineCommand
(
"night_mode"
,
toggleNightMode
,
F
(
"(Toggles night mode on/off)"
));
sensor_console
::
defineIntCommand
(
"color"
,
showColor
,
F
(
"0xFF0015 (Shows color, specified as RGB, for debugging)"
));
}
void
toggleNightMode
()
{
...
...
ampel-firmware/lorawan.cpp
View file @
06467a3d
...
...
@@ -47,7 +47,7 @@ namespace lorawan {
LMIC_reset
();
// Join, but don't send anything yet.
LMIC_startJoining
();
sensor_console
::
defineIntCommand
(
"lora"
,
setLoRaInterval
,
F
(
"
300 (Sets LoRaWAN sending interval, in s)"
));
sensor_console
::
defineIntCommand
(
"lora"
,
setLoRaInterval
,
F
(
"300 (Sets LoRaWAN sending interval, in s)"
));
}
// Checks if OTAA is connected, or if payload should be sent.
...
...
@@ -96,7 +96,7 @@ namespace lorawan {
printHex2
(
artKey
[
i
]);
}
Serial
.
println
();
Serial
.
print
(
" NwkSKey: "
);
Serial
.
print
(
F
(
" NwkSKey: "
)
)
;
for
(
size_t
i
=
0
;
i
<
sizeof
(
nwkKey
);
++
i
)
{
if
(
i
!=
0
)
Serial
.
print
(
"-"
);
...
...
ampel-firmware/mqtt.cpp
View file @
06467a3d
...
...
@@ -36,9 +36,9 @@ namespace mqtt {
// mqttClient.setSocketTimeout(config::mqtt_timeout); //NOTE: somehow doesn't seem to have any effect on connect()
mqttClient
.
setServer
(
config
::
mqtt_server
,
config
::
mqtt_port
);
sensor_console
::
defineIntCommand
(
"mqtt"
,
setMQTTinterval
,
F
(
"
60 (Sets MQTT sending interval, in s)"
));
sensor_console
::
defineIntCommand
(
"mqtt"
,
setMQTTinterval
,
F
(
"60 (Sets MQTT sending interval, in s)"
));
sensor_console
::
defineCommand
(
"send_local_ip"
,
sendInfoAboutLocalNetwork
,
F
(
"
(Sends local IP and SSID via MQTT. Can be useful to find sensor)"
));
F
(
"(Sends local IP and SSID via MQTT. Can be useful to find sensor)"
));
}
void
publish
(
const
char
*
timestamp
,
int16_t
co2
,
float
temperature
,
float
humidity
)
{
...
...
@@ -79,7 +79,7 @@ namespace mqtt {
command
[
i
]
=
message
[
i
];
}
command
[
length
]
=
0
;
sensor_console
::
runCommand
(
command
);
sensor_console
::
execute
(
command
);
led_effects
::
onBoardLEDOff
();
}
...
...
ampel-firmware/sensor_console.cpp
View file @
06467a3d
...
...
@@ -6,75 +6,112 @@ namespace sensor_console {
uint8_t
commands_count
=
0
;
enum
input_type
{
NONE
,
INT32
,
STRING
};
struct
Command
{
const
char
*
name
;
union
{
void
(
*
voidFunction
)();
void
(
*
intFunction
)(
int32_t
);
void
(
*
void
Function
)(
void
);
void
(
*
str
Function
)(
char
*
);
};
const
char
*
doc
;
bool
has_parameter
;
input_type
parameter_type
;
};
struct
CommandLine
{
char
function_name
[
MAX_COMMAND_SIZE
];
input_type
argument_type
;
int32_t
int_argument
;
char
str_argument
[
MAX_COMMAND_SIZE
];
};
Command
commands
[
MAX_COMMANDS
];
//NOTE: Probably possible to DRY (with templates?)
void
defineCommand
(
const
char
*
name
,
void
(
*
function
)(
void
),
const
__FlashStringHelper
*
doc_fstring
)
{
const
char
*
doc
=
(
const
char
*
)
doc_fstring
;
bool
addCommand
(
const
char
*
name
,
const
__FlashStringHelper
*
doc_fstring
)
{
if
(
commands_count
<
MAX_COMMANDS
)
{
commands
[
commands_count
].
name
=
name
;
commands
[
commands_count
].
voidFunction
=
function
;
commands
[
commands_count
].
doc
=
doc
;
commands
[
commands_count
].
has_parameter
=
false
;
commands_count
++
;
commands
[
commands_count
].
doc
=
(
const
char
*
)
doc_fstring
;
return
true
;
}
else
{
Serial
.
println
(
F
(
"Too many commands have been defined."
));
return
false
;
}
}
void
defineCommand
(
const
char
*
name
,
void
(
*
function
)(),
const
__FlashStringHelper
*
doc_fstring
)
{
if
(
addCommand
(
name
,
doc_fstring
))
{
commands
[
commands_count
].
voidFunction
=
function
;
commands
[
commands_count
++
].
parameter_type
=
NONE
;
}
}
void
defineIntCommand
(
const
char
*
name
,
void
(
*
function
)(
int32_t
),
const
__FlashStringHelper
*
doc_fstring
)
{
const
char
*
doc
=
(
const
char
*
)
doc_fstring
;
if
(
commands_count
<
MAX_COMMANDS
)
{
commands
[
commands_count
].
name
=
name
;
if
(
addCommand
(
name
,
doc_fstring
))
{
commands
[
commands_count
].
intFunction
=
function
;
commands
[
commands_count
].
doc
=
doc
;
commands
[
commands_count
].
has_parameter
=
true
;
commands_count
++
;
}
else
{
Serial
.
println
(
F
(
"Too many commands have been defined."
));
commands
[
commands_count
++
].
parameter_type
=
INT32
;
}
}
void
defineStringCommand
(
const
char
*
name
,
void
(
*
function
)(
char
*
),
const
__FlashStringHelper
*
doc_fstring
)
{
if
(
addCommand
(
name
,
doc_fstring
))
{
commands
[
commands_count
].
strFunction
=
function
;
commands
[
commands_count
++
].
parameter_type
=
STRING
;
}
}
/*
* Tries to split a string command (e.g. 'mqtt 60' or 'show_csv') into
a function_name and an argument.
*
Returns 0 if both are found, 1 if there is a problem and 2 if no argument is found.
* Tries to split a string command (e.g. 'mqtt 60' or 'show_csv') into
*
a CommandLine struct (function_name, argument_type and argument)
*/
uint8_t
parseCommand
(
const
char
*
command
,
char
*
function_name
,
int32_t
&
argument
)
{
char
split_command
[
MAX_COMMAND_SIZE
];
strlcpy
(
split_command
,
command
,
MAX_COMMAND_SIZE
);
char
*
arg
;
char
*
part1
;
part1
=
strtok
(
split_command
,
" "
);
if
(
!
part1
)
{
void
parseCommand
(
const
char
*
command
,
CommandLine
&
command_line
)
{
if
(
strlen
(
command
)
==
0
)
{
Serial
.
println
(
F
(
"Received empty command"
));
// Empty string
return
1
;
command_line
.
argument_type
=
NONE
;
return
;
}
strlcpy
(
function_name
,
part1
,
MAX_COMMAND_SIZE
);
arg
=
strtok
(
NULL
,
" "
);
uint8_t
code
=
0
;
if
(
arg
)
{
char
*
end
;
argument
=
strtol
(
arg
,
&
end
,
10
);
if
(
*
end
)
{
// Second argument isn't a number
code
=
2
;
}
char
*
first_space
;
first_space
=
strchr
(
command
,
' '
);
if
(
first_space
==
NULL
)
{
command_line
.
argument_type
=
NONE
;
strlcpy
(
command_line
.
function_name
,
command
,
MAX_COMMAND_SIZE
);
return
;
}
strlcpy
(
command_line
.
function_name
,
command
,
first_space
-
command
+
1
);
strlcpy
(
command_line
.
str_argument
,
first_space
+
1
,
MAX_COMMAND_SIZE
-
(
first_space
-
command
)
-
1
);
char
*
end
;
command_line
.
int_argument
=
strtol
(
command_line
.
str_argument
,
&
end
,
0
);
// Accepts 123 or 0xFF00FF
if
(
*
end
)
{
command_line
.
argument_type
=
STRING
;
}
else
{
// No argument
code
=
2
;
command_line
.
argument_type
=
INT32
;
}
}
int
compareCommandNames
(
const
void
*
s1
,
const
void
*
s2
)
{
struct
Command
*
c1
=
(
struct
Command
*
)
s1
;
struct
Command
*
c2
=
(
struct
Command
*
)
s2
;
return
strcmp
(
c1
->
name
,
c2
->
name
);
}
void
listAvailableCommands
()
{
qsort
(
commands
,
commands_count
,
sizeof
(
commands
[
0
]),
compareCommandNames
);
for
(
uint8_t
i
=
0
;
i
<
commands_count
;
i
++
)
{
Serial
.
print
(
F
(
" "
));
Serial
.
print
(
commands
[
i
].
name
);
Serial
.
print
(
F
(
" "
));
Serial
.
print
(
commands
[
i
].
doc
);
Serial
.
println
(
F
(
"."
));
}
return
code
;
}
/*
...
...
@@ -88,7 +125,7 @@ namespace sensor_console {
case
'\n'
:
// end of text
Serial
.
println
();
input_line
[
input_pos
]
=
0
;
runCommand
(
input_line
);
execute
(
input_line
);
input_pos
=
0
;
break
;
case
'\r'
:
// discard carriage return
...
...
@@ -112,50 +149,40 @@ namespace sensor_console {
}
}
int
compareName
(
const
void
*
s1
,
const
void
*
s2
)
{
struct
Command
*
c1
=
(
struct
Command
*
)
s1
;
struct
Command
*
c2
=
(
struct
Command
*
)
s2
;
return
strcmp
(
c1
->
name
,
c2
->
name
);
}
void
listAvailableCommands
()
{
qsort
(
commands
,
commands_count
,
sizeof
(
commands
[
0
]),
compareName
);
for
(
uint8_t
i
=
0
;
i
<
commands_count
;
i
++
)
{
Serial
.
print
(
" "
);
Serial
.
print
(
commands
[
i
].
name
);
Serial
.
print
(
commands
[
i
].
doc
);
Serial
.
println
(
"."
);
}
}
/*
* Tries to find the corresponding callback for a given command. Name and
number of argument
should fit.
* Tries to find the corresponding callback for a given command. Name and
parameter type
should fit.
*/
void
runCommand
(
const
char
*
command
)
{
char
function_name
[
MAX_COMMAND_SIZE
];
int32_t
argument
=
0
;
bool
has_argument
;
has_argument
=
(
parseCommand
(
command
,
function_name
,
argument
)
==
0
);
void
execute
(
const
char
*
command_str
)
{
CommandLine
input
;
parseCommand
(
command_str
,
input
);
for
(
uint8_t
i
=
0
;
i
<
commands_count
;
i
++
)
{
if
(
!
strcmp
(
function_name
,
commands
[
i
].
name
)
&&
has_
argument
==
commands
[
i
].
has_
parameter
)
{
if
(
!
strcmp
(
input
.
function_name
,
commands
[
i
].
name
)
&&
input
.
argument
_type
==
commands
[
i
].
parameter
_type
)
{
Serial
.
print
(
F
(
"Calling : "
));
Serial
.
print
(
function_name
);
if
(
has_argument
)
{
Serial
.
print
(
F
(
"("
));
Serial
.
print
(
argument
);
Serial
.
println
(
F
(
")"
));
commands
[
i
].
intFunction
(
argument
);
}
else
{
Serial
.
print
(
input
.
function_name
);
switch
(
input
.
argument_type
)
{
case
NONE
:
Serial
.
println
(
F
(
"()"
));
commands
[
i
].
voidFunction
();
return
;
case
INT32
:
Serial
.
print
(
F
(
"("
));
Serial
.
print
(
input
.
int_argument
);
Serial
.
println
(
F
(
")"
));
commands
[
i
].
intFunction
(
input
.
int_argument
);
return
;
case
STRING
:
Serial
.
print
(
F
(
"('"
));
Serial
.
print
(
input
.
str_argument
);
Serial
.
println
(
F
(
"')"
));
commands
[
i
].
strFunction
(
input
.
str_argument
);
return
;
}
return
;
}
}
Serial
.
print
(
F
(
"'"
));
Serial
.
print
(
command
);
Serial
.
print
(
command
_str
);
Serial
.
println
(
F
(
"' not supported. Available commands :"
));
listAvailableCommands
();
}
}
ampel-firmware/sensor_console.h
View file @
06467a3d
...
...
@@ -8,11 +8,13 @@
*/
namespace
sensor_console
{
void
defineCommand
(
const
char
*
command
,
void
(
*
function
)(
void
),
const
__FlashStringHelper
*
ifsh
);
void
defineIntCommand
(
const
char
*
command
,
void
(
*
function
)(
int32_t
),
const
__FlashStringHelper
*
ifsh
);
void
defineCommand
(
const
char
*
name
,
void
(
*
function
)(),
const
__FlashStringHelper
*
doc_fstring
);
void
defineIntCommand
(
const
char
*
name
,
void
(
*
function
)(
int32_t
),
const
__FlashStringHelper
*
doc_fstring
);
void
defineStringCommand
(
const
char
*
name
,
void
(
*
function
)(
char
*
),
const
__FlashStringHelper
*
doc_fstring
);
void
processSerialInput
(
const
byte
in_byte
);
void
runCommand
(
const
char
*
command
);
void
execute
(
const
char
*
command_line
);
}
#endif
ampel-firmware/util.cpp
View file @
06467a3d
...
...
@@ -74,11 +74,11 @@ char* getSensorId() {
Ampel
::
Ampel
()
:
board
(
current_board
),
sensorId
(
getSensorId
()),
max_loop_duration
(
0
)
{
sensor_console
::
defineIntCommand
(
"set_time"
,
ntp
::
setLocalTime
,
F
(
"
1618829570 (Sets time to the given UNIX time)"
));
sensor_console
::
defineCommand
(
"free"
,
Ampel
::
showFreeSpace
,
F
(
"
(Displays available heap space)"
));
sensor_console
::
defineIntCommand
(
"set_time"
,
ntp
::
setLocalTime
,
F
(
"1618829570 (Sets time to the given UNIX time)"
));
sensor_console
::
defineCommand
(
"free"
,
Ampel
::
showFreeSpace
,
F
(
"(Displays available heap space)"
));
sensor_console
::
defineCommand
(
"reset"
,
[]()
{
ESP
.
restart
();
},
F
(
"
(Restarts the sensor)"
));
},
F
(
"(Restarts the sensor)"
));
}
Ampel
ampel
;
ampel-firmware/web_server.cpp
View file @
06467a3d
...
...
@@ -292,7 +292,7 @@ namespace web_server {
}
http
.
sendHeader
(
"Location"
,
"/"
);
http
.
send
(
303
);
sensor_console
::
runCommand
(
http
.
arg
(
"send"
).
c_str
());
sensor_console
::
execute
(
http
.
arg
(
"send"
).
c_str
());
}
void
handlePageNotFound
()
{
...
...
ampel-firmware/wifi_util.cpp
View file @
06467a3d
...
...
@@ -43,8 +43,8 @@ namespace wifi {
// Initialize Wi-Fi
void
connect
(
const
char
*
hostname
)
{
sensor_console
::
defineCommand
(
"wifi_scan"
,
scanNetworks
,
F
(
"
(Scans available WiFi networks)"
));
sensor_console
::
defineCommand
(
"local_ip"
,
showLocalIp
,
F
(
"
(Displays local IP and current SSID)"
));
sensor_console
::
defineCommand
(
"wifi_scan"
,
scanNetworks
,
F
(
"(Scans available WiFi networks)"
));
sensor_console
::
defineCommand
(
"local_ip"
,
showLocalIp
,
F
(
"(Displays local IP and current SSID)"
));
//NOTE: WiFi Multi could allow multiple SSID and passwords.
WiFi
.
persistent
(
false
);
// Don't write user & password to Flash.
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment