Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
co2ampel
ampel-firmware
Commits
1d090ccc
Commit
1d090ccc
authored
Mar 03, 2022
by
Eric Duminil
Browse files
Too long but kinda working
parent
d741d85f
Changes
1
Hide whitespace changes
Inline
Side-by-side
ampel-firmware/ampel-firmware.ino
View file @
1d090ccc
/**
* IotWebConf03TypedParameters.ino -- IotWebConf is an ESP8266/ESP32
* non blocking WiFi/AP web configuration library for Arduino.
* https://github.com/prampec/IotWebConf
*
* Copyright (C) 2020 Balazs Kelemen <prampec+arduino@gmail.com>
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
#include <IotWebConf.h>
#include <IotWebConfTParameter.h>
/**
* Example: Custom parameters
* Description:
* Typed Parameters are a new approach to store/handle parameter data.
* This part of the software is very experimental, and certainly
* not recommended for beginners.
* The goal of this particular example is to compare the original
* approach of IotWebConf03CustomParameters to this new typed
* parameters, as both examples should work the same.
*
* Hardware setup for this example:
* - An LED is attached to LED_BUILTIN pin with setup On=LOW.
* - [Optional] A push button is attached to pin D2, the other leg of the
* button should be attached to GND.
/** Other scripts can use this namespace, in order to define commands, via callbacks.
* Those callbacks can then be used to send commands to the sensor (reset, calibrate, led on/off, ...)
* The callbacks can either have no parameter, one int32_t parameter or one char pointer.
*/
#include <IotWebConf.h>
#include <IotWebConfTParameter.h>
namespace
sensor_console
{
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
checkSerialInput
();
void
execute
(
const
char
*
command_line
);
}
// -- Initial name of the Thing. Used e.g. as SSID of the own Access Point.
const
char
thingName
[]
=
"testThing"
;
...
...
@@ -38,16 +26,7 @@ const char wifiInitialApPassword[] = "smrtTHNG8266";
#define NUMBER_LEN 32
// -- Configuration specific key. The value should be modified if config structure was changed.
#define CONFIG_VERSION "dem4"
// -- When CONFIG_PIN is pulled to ground on startup, the Thing will use the initial
// password to buld an AP. (E.g. in case of lost password)
#define CONFIG_PIN 2 // D2
// -- Status indicator pin.
// First it will light up (kept LOW), on Wifi connection it will blink,
// when connected to the Wifi it will turn off (kept HIGH).
#define STATUS_PIN LED_BUILTIN
#define CONFIG_VERSION "dem99"
// -- Method declarations.
void
handleRoot
();
...
...
@@ -129,8 +108,6 @@ void setup()
group2
.
addItem
(
&
dateParam
);
group2
.
addItem
(
&
timeParam
);
iotWebConf
.
setStatusPin
(
STATUS_PIN
);
iotWebConf
.
setConfigPin
(
CONFIG_PIN
);
iotWebConf
.
addSystemParameter
(
&
stringParam
);
iotWebConf
.
addParameterGroup
(
&
group1
);
iotWebConf
.
addParameterGroup
(
&
group2
);
...
...
@@ -144,6 +121,34 @@ void setup()
server
.
on
(
"/"
,
handleRoot
);
server
.
on
(
"/config"
,
[]{
iotWebConf
.
handleConfig
();
});
server
.
onNotFound
([](){
iotWebConf
.
handleNotFound
();
});
sensor_console
::
defineCommand
(
"reset"
,
[](){
ESP
.
restart
();
},
F
(
"(Restarts the ESP)"
));
sensor_console
::
defineCommand
(
"save_config"
,
[](){
iotWebConf
.
saveConfig
();
},
F
(
"(Saves the config to EEPROM)"
));
sensor_console
::
defineCommand
(
"reset_config"
,
[]()
{
Serial
.
println
(
F
(
"Resetting config..."
));
iotWebConf
.
getRootParameterGroup
()
->
applyDefaultValue
();
Serial
.
println
(
F
(
"Done!"
));
},
F
(
"(Resets the complete IotWeb config)"
));
sensor_console
::
defineStringCommand
(
"ssid"
,
[](
char
*
ssid
)
{
Serial
.
print
(
F
(
"Setting WiFi ssid to "
));
Serial
.
println
(
ssid
);
strlcpy
(
iotWebConf
.
getWifiSsidParameter
()
->
valueBuffer
,
ssid
,
iotWebConf
.
getWifiSsidParameter
()
->
getLength
());
},
F
(
"name (Sets SSID to name)"
));
sensor_console
::
defineStringCommand
(
"wifi_pwd"
,
[](
char
*
pwd
)
{
Serial
.
print
(
F
(
"Setting WiFi password to "
));
Serial
.
println
(
pwd
);
strlcpy
(
iotWebConf
.
getWifiPasswordParameter
()
->
valueBuffer
,
pwd
,
iotWebConf
.
getWifiPasswordParameter
()
->
getLength
());
},
F
(
"abc (Sets WiFi password to abc)"
));
sensor_console
::
defineStringCommand
(
"ap_pwd"
,
[](
char
*
pwd
)
{
Serial
.
print
(
F
(
"Setting AP password to "
));
Serial
.
println
(
pwd
);
strlcpy
(
iotWebConf
.
getWifiPasswordParameter
()
->
valueBuffer
,
pwd
,
iotWebConf
.
getWifiPasswordParameter
()
->
getLength
());
},
F
(
"abc (Sets AP password to abc)"
));
Serial
.
println
(
"Ready."
);
}
...
...
@@ -152,6 +157,7 @@ void loop()
{
// -- doLoop should be called as frequently as possible.
iotWebConf
.
doLoop
();
sensor_console
::
checkSerialInput
();
}
/**
...
...
@@ -198,3 +204,199 @@ void configSaved()
{
Serial
.
println
(
"Configuration was updated."
);
}
/***
* Sensor console
*/
namespace
sensor_console
{
const
uint8_t
MAX_COMMANDS
=
10
;
const
uint8_t
MAX_COMMAND_SIZE
=
40
;
uint8_t
commands_count
=
0
;
enum
input_type
{
NONE
,
INT32
,
STRING
};
struct
Command
{
const
char
*
name
;
union
{
void
(
*
voidFunction
)();
void
(
*
intFunction
)(
int32_t
);
void
(
*
strFunction
)(
char
*
);
};
const
char
*
doc
;
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
];
bool
addCommand
(
const
char
*
name
,
const
__FlashStringHelper
*
doc_fstring
)
{
if
(
commands_count
<
MAX_COMMANDS
)
{
commands
[
commands_count
].
name
=
name
;
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
)
{
if
(
addCommand
(
name
,
doc_fstring
))
{
commands
[
commands_count
].
intFunction
=
function
;
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 CommandLine struct (function_name, argument_type and argument)
*/
void
parseCommand
(
const
char
*
command
,
CommandLine
&
command_line
)
{
if
(
strlen
(
command
)
==
0
)
{
Serial
.
println
(
F
(
"Received empty command"
));
command_line
.
argument_type
=
NONE
;
return
;
}
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
{
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
(
"."
));
}
}
/*
* Saves bytes from Serial.read() until enter is pressed, and tries to run the corresponding command.
* http://www.gammon.com.au/serial
*/
void
processSerialInput
(
const
byte
input_byte
)
{
static
char
input_line
[
MAX_COMMAND_SIZE
];
static
unsigned
int
input_pos
=
0
;
switch
(
input_byte
)
{
case
'\n'
:
// end of text
Serial
.
println
();
input_line
[
input_pos
]
=
0
;
execute
(
input_line
);
input_pos
=
0
;
break
;
case
'\r'
:
// discard carriage return
break
;
case
'\b'
:
// backspace
if
(
input_pos
>
0
)
{
input_pos
--
;
Serial
.
print
(
F
(
"
\b
\b
"
));
}
break
;
default:
if
(
input_pos
==
0
)
{
Serial
.
print
(
F
(
"> "
));
}
// keep adding if not full ... allow for terminating null byte
if
(
input_pos
<
(
MAX_COMMAND_SIZE
-
1
))
{
input_line
[
input_pos
++
]
=
input_byte
;
Serial
.
print
((
char
)
input_byte
);
}
break
;
}
}
void
checkSerialInput
()
{
while
(
Serial
.
available
()
>
0
)
{
sensor_console
::
processSerialInput
(
Serial
.
read
());
}
}
/*
* Tries to find the corresponding callback for a given command. Name and parameter type should fit.
*/
void
execute
(
const
char
*
command_str
)
{
CommandLine
input
;
parseCommand
(
command_str
,
input
);
for
(
uint8_t
i
=
0
;
i
<
commands_count
;
i
++
)
{
if
(
!
strcmp
(
input
.
function_name
,
commands
[
i
].
name
)
&&
input
.
argument_type
==
commands
[
i
].
parameter_type
)
{
Serial
.
print
(
F
(
"Calling : "
));
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
;
}
}
}
Serial
.
print
(
F
(
"'"
));
Serial
.
print
(
command_str
);
Serial
.
println
(
F
(
"' not supported. Available commands :"
));
listAvailableCommands
();
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a 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