mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 15:59:52 +03:00
updated gpio test logic
This commit is contained in:
@@ -360,7 +360,7 @@ const Sensors = () => {
|
|||||||
v: 0,
|
v: 0,
|
||||||
o: 0,
|
o: 0,
|
||||||
f: 1,
|
f: 1,
|
||||||
t: AnalogType.NOTUSED,
|
t: AnalogType.DIGITAL_IN, // default to digital in 1
|
||||||
d: false,
|
d: false,
|
||||||
s: false,
|
s: false,
|
||||||
o_n: ''
|
o_n: ''
|
||||||
@@ -462,7 +462,7 @@ const Sensors = () => {
|
|||||||
>
|
>
|
||||||
<Cell stiff>{as.g}</Cell>
|
<Cell stiff>{as.g}</Cell>
|
||||||
<Cell>{as.n}</Cell>
|
<Cell>{as.n}</Cell>
|
||||||
<Cell stiff>{AnalogTypeNames[as.t]} </Cell>
|
<Cell stiff>{AnalogTypeNames[as.t - 1]} </Cell>
|
||||||
{(as.t === AnalogType.DIGITAL_OUT &&
|
{(as.t === AnalogType.DIGITAL_OUT &&
|
||||||
as.g !== GPIO_25 &&
|
as.g !== GPIO_25 &&
|
||||||
as.g !== GPIO_26) ||
|
as.g !== GPIO_26) ||
|
||||||
@@ -470,9 +470,7 @@ const Sensors = () => {
|
|||||||
as.t === AnalogType.PULSE ? (
|
as.t === AnalogType.PULSE ? (
|
||||||
<Cell stiff>{as.v ? LL.ON() : LL.OFF()}</Cell>
|
<Cell stiff>{as.v ? LL.ON() : LL.OFF()}</Cell>
|
||||||
) : (
|
) : (
|
||||||
<Cell stiff>
|
<Cell stiff>{formatValue(as.v, as.u)}</Cell>
|
||||||
{as.t !== AnalogType.NOTUSED ? formatValue(as.v, as.u) : ''}
|
|
||||||
</Cell>
|
|
||||||
)}
|
)}
|
||||||
</Row>
|
</Row>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ const SensorsAnalogDialog = ({
|
|||||||
const analogTypeMenuItems = useMemo(
|
const analogTypeMenuItems = useMemo(
|
||||||
() =>
|
() =>
|
||||||
AnalogTypeNames.map((val, i) => (
|
AnalogTypeNames.map((val, i) => (
|
||||||
<MenuItem key={val} value={i}>
|
<MenuItem key={val} value={i + 1}>
|
||||||
{val}
|
{val}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)),
|
)),
|
||||||
|
|||||||
@@ -231,7 +231,6 @@ export const DeviceValueUOM_s = [
|
|||||||
|
|
||||||
export enum AnalogType {
|
export enum AnalogType {
|
||||||
REMOVED = -1,
|
REMOVED = -1,
|
||||||
NOTUSED = 0,
|
|
||||||
DIGITAL_IN = 1,
|
DIGITAL_IN = 1,
|
||||||
COUNTER = 2,
|
COUNTER = 2,
|
||||||
ADC = 3,
|
ADC = 3,
|
||||||
@@ -250,22 +249,21 @@ export enum AnalogType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const AnalogTypeNames = [
|
export const AnalogTypeNames = [
|
||||||
'(disabled)',
|
'Digital In', // 1
|
||||||
'Digital In',
|
'Counter', // 2
|
||||||
'Counter',
|
'ADC In', // 3
|
||||||
'ADC In',
|
'Timer', // 4
|
||||||
'Timer',
|
'Rate', // 5
|
||||||
'Rate',
|
'Digital Out', // 6
|
||||||
'Digital Out',
|
'PWM 0', // 7
|
||||||
'PWM 0',
|
'PWM 1', // 8
|
||||||
'PWM 1',
|
'PWM 2', // 9
|
||||||
'PWM 2',
|
'NTC Temp.', // 10
|
||||||
'NTC Temp.',
|
'RGB Led', // 11
|
||||||
'RGB Led',
|
'Pulse', // 12
|
||||||
'Pulse',
|
'Freq 0', // 13
|
||||||
'Freq 0',
|
'Freq 1', // 14
|
||||||
'Freq 1',
|
'Freq 2', // 15
|
||||||
'Freq 2'
|
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
export const BOARD_PROFILES = {
|
export const BOARD_PROFILES = {
|
||||||
|
|||||||
@@ -984,7 +984,7 @@ const emsesp_sensordata = {
|
|||||||
],
|
],
|
||||||
// as: [],
|
// as: [],
|
||||||
as: [
|
as: [
|
||||||
{ id: 1, g: 35, n: 'motor', v: 0, u: 0, o: 17, f: 0, t: 0, d: false, s: false },
|
{ id: 1, g: 35, n: 'motor', v: 0, u: 0, o: 17, f: 0, t: 7, d: false, s: false },
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
g: 34,
|
g: 34,
|
||||||
|
|||||||
@@ -831,7 +831,6 @@ notoken
|
|||||||
NOTOKEN
|
NOTOKEN
|
||||||
NOTRANSLATION
|
NOTRANSLATION
|
||||||
NOTSET
|
NOTSET
|
||||||
NOTUSED
|
|
||||||
NOTYPE
|
NOTYPE
|
||||||
nrgconscomp
|
nrgconscomp
|
||||||
nrgconscompcooling
|
nrgconscompcooling
|
||||||
|
|||||||
@@ -155,12 +155,12 @@ void AnalogSensor::reload(bool get_nvs) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
|
// it's new
|
||||||
// check if the GPIO is valid before registering. If not, force set the sensor to disabled, but don't remove it
|
// check if the GPIO is valid before registering. If not, force set the sensor to disabled, but don't remove it
|
||||||
// should only trigger if uploading a customization file with invalid gpios.
|
// should only trigger if uploading a customization file with invalid gpios.
|
||||||
AnalogType type = static_cast<AnalogType>(sensor.type);
|
AnalogType type = static_cast<AnalogType>(sensor.type);
|
||||||
if (!EMSESP::system_.is_valid_gpio(sensor.gpio)) {
|
if (!EMSESP::system_.check_valid_gpio(sensor.gpio, "Analog Sensor")) {
|
||||||
LOG_WARNING("Bad GPIO %d for Sensor %s. Disabling.", sensor.gpio, sensor.name.c_str());
|
continue;
|
||||||
type = AnalogType::NOTUSED;
|
|
||||||
}
|
}
|
||||||
sensors_.emplace_back(sensor.gpio, sensor.name, sensor.offset, sensor.factor, sensor.uom, type, sensor.is_system);
|
sensors_.emplace_back(sensor.gpio, sensor.name, sensor.offset, sensor.factor, sensor.uom, type, sensor.is_system);
|
||||||
|
|
||||||
@@ -171,6 +171,8 @@ void AnalogSensor::reload(bool get_nvs) {
|
|||||||
sensors_.back().set_value(0); // reset value only for new sensors
|
sensors_.back().set_value(0); // reset value only for new sensors
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add the command to set the value of the sensor
|
||||||
if (sensor.type == AnalogType::COUNTER || (sensor.type >= AnalogType::DIGITAL_OUT && sensor.type <= AnalogType::PWM_2)
|
if (sensor.type == AnalogType::COUNTER || (sensor.type >= AnalogType::DIGITAL_OUT && sensor.type <= AnalogType::PWM_2)
|
||||||
|| sensor.type == AnalogType::RGB || sensor.type == AnalogType::PULSE) {
|
|| sensor.type == AnalogType::RGB || sensor.type == AnalogType::PULSE) {
|
||||||
Command::add(
|
Command::add(
|
||||||
@@ -522,8 +524,8 @@ bool AnalogSensor::update(uint8_t gpio, std::string & name, double offset, doubl
|
|||||||
}
|
}
|
||||||
|
|
||||||
// we didn't find it, it's new, so create and store it in the customization list
|
// we didn't find it, it's new, so create and store it in the customization list
|
||||||
// gpio is already checked in web interface
|
// gpio is already checked if valid in the webUI
|
||||||
if (!found_sensor && EMSESP::system_.is_valid_gpio(gpio)) {
|
if (!found_sensor) {
|
||||||
found_sensor = true;
|
found_sensor = true;
|
||||||
EMSESP::webCustomizationService.update([&](WebCustomization & settings) {
|
EMSESP::webCustomizationService.update([&](WebCustomization & settings) {
|
||||||
auto newSensor = AnalogCustomization();
|
auto newSensor = AnalogCustomization();
|
||||||
@@ -626,7 +628,6 @@ void AnalogSensor::publish_values(const bool force) {
|
|||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
|
|
||||||
for (auto & sensor : sensors_) {
|
for (auto & sensor : sensors_) {
|
||||||
if (sensor.type() != AnalogType::NOTUSED) {
|
|
||||||
if (Mqtt::is_nested()) {
|
if (Mqtt::is_nested()) {
|
||||||
char s[10];
|
char s[10];
|
||||||
JsonObject dataSensor = doc[Helpers::smallitoa(s, sensor.gpio())].to<JsonObject>();
|
JsonObject dataSensor = doc[Helpers::smallitoa(s, sensor.gpio())].to<JsonObject>();
|
||||||
@@ -779,7 +780,6 @@ void AnalogSensor::publish_values(const bool force) {
|
|||||||
sensor.ha_registered = Mqtt::queue_ha(topic, config.as<JsonObject>());
|
sensor.ha_registered = Mqtt::queue_ha(topic, config.as<JsonObject>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||||
snprintf(topic, sizeof(topic), "%s_data", F_(analogsensor));
|
snprintf(topic, sizeof(topic), "%s_data", F_(analogsensor));
|
||||||
|
|||||||
@@ -118,7 +118,6 @@ class AnalogSensor {
|
|||||||
~AnalogSensor() = default;
|
~AnalogSensor() = default;
|
||||||
|
|
||||||
enum AnalogType : int8_t {
|
enum AnalogType : int8_t {
|
||||||
NOTUSED = 0, // 0 = disabled
|
|
||||||
DIGITAL_IN = 1,
|
DIGITAL_IN = 1,
|
||||||
COUNTER = 2,
|
COUNTER = 2,
|
||||||
ADC = 3,
|
ADC = 3,
|
||||||
@@ -164,12 +163,10 @@ class AnalogSensor {
|
|||||||
return (!sensors_.empty());
|
return (!sensors_.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// count number of items in sensors_ where type is not set to disabled and not a system sensor
|
||||||
size_t count_entities(bool exclude_disabled_system = false) const {
|
size_t count_entities(bool exclude_disabled_system = false) const {
|
||||||
if (exclude_disabled_system) {
|
if (exclude_disabled_system) {
|
||||||
// count number of items in sensors_ where type is not set to disabled and not a system sensor
|
return std::count_if(sensors_.begin(), sensors_.end(), [](const Sensor & sensor) { return !sensor.is_system(); });
|
||||||
return std::count_if(sensors_.begin(), sensors_.end(), [](const Sensor & sensor) {
|
|
||||||
return sensor.type() != AnalogSensor::AnalogType::NOTUSED && !sensor.is_system();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return sensors_.size();
|
return sensors_.size();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -321,7 +321,7 @@ static void setup_commands(std::shared_ptr<Commands> const & commands) {
|
|||||||
return StateUpdateResult::CHANGED;
|
return StateUpdateResult::CHANGED;
|
||||||
});
|
});
|
||||||
shell.printfln("Loaded board profile %s", board_profile.c_str());
|
shell.printfln("Loaded board profile %s", board_profile.c_str());
|
||||||
EMSESP::system_.network_init(true);
|
EMSESP::system_.network_init();
|
||||||
});
|
});
|
||||||
|
|
||||||
commands->add_command(
|
commands->add_command(
|
||||||
@@ -357,7 +357,7 @@ static void setup_commands(std::shared_ptr<Commands> const & commands) {
|
|||||||
shell.printfln(F_(tx_mode_fmt), settings.tx_mode);
|
shell.printfln(F_(tx_mode_fmt), settings.tx_mode);
|
||||||
return StateUpdateResult::CHANGED;
|
return StateUpdateResult::CHANGED;
|
||||||
});
|
});
|
||||||
EMSESP::system_.uart_init(false);
|
EMSESP::system_.uart_init();
|
||||||
});
|
});
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -1665,6 +1665,9 @@ void EMSESP::start() {
|
|||||||
bool factory_settings = false;
|
bool factory_settings = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// set valid GPIOs list based on ESP32 board/platform type
|
||||||
|
system_.set_valid_system_gpios();
|
||||||
|
|
||||||
// start web log service. now we can start capturing logs to the web log
|
// start web log service. now we can start capturing logs to the web log
|
||||||
webLogService.begin();
|
webLogService.begin();
|
||||||
|
|
||||||
@@ -1714,7 +1717,7 @@ void EMSESP::start() {
|
|||||||
};
|
};
|
||||||
LOG_INFO("Library loaded: %d EMS devices, %d device entities, %s", device_library_.size(), EMSESP_TRANSLATION_COUNT, system_.languages_string().c_str());
|
LOG_INFO("Library loaded: %d EMS devices, %d device entities, %s", device_library_.size(), EMSESP_TRANSLATION_COUNT, system_.languages_string().c_str());
|
||||||
|
|
||||||
system_.reload_settings(); // ... and store some of the settings locally
|
system_.get_settings(); // ... and store some of the settings locally
|
||||||
|
|
||||||
webCustomizationService.begin(); // load the customizations
|
webCustomizationService.begin(); // load the customizations
|
||||||
webSchedulerService.begin(); // load the scheduler events
|
webSchedulerService.begin(); // load the scheduler events
|
||||||
@@ -1806,6 +1809,14 @@ void EMSESP::loop() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (EMSESP::system_.systemStatus() == SYSTEM_STATUS::SYSTEM_STATUS_INVALID_GPIO) {
|
||||||
|
static bool only_once = false;
|
||||||
|
if (!only_once) {
|
||||||
|
LOG_ERROR("Invalid GPIOs used in settings. Please check your settings.");
|
||||||
|
only_once = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uuid::loop();
|
uuid::loop();
|
||||||
|
|
||||||
#ifndef EMSESP_STANDALONE
|
#ifndef EMSESP_STANDALONE
|
||||||
|
|||||||
@@ -91,6 +91,8 @@ PButton System::myPButton_;
|
|||||||
bool System::test_set_all_active_ = false;
|
bool System::test_set_all_active_ = false;
|
||||||
uint32_t System::max_alloc_mem_;
|
uint32_t System::max_alloc_mem_;
|
||||||
uint32_t System::heap_mem_;
|
uint32_t System::heap_mem_;
|
||||||
|
std::vector<uint8_t> System::valid_system_gpios_;
|
||||||
|
std::vector<uint8_t> System::used_gpios_;
|
||||||
|
|
||||||
// find the index of the language
|
// find the index of the language
|
||||||
// 0 = EN, 1 = DE, etc...
|
// 0 = EN, 1 = DE, etc...
|
||||||
@@ -404,19 +406,18 @@ void System::syslog_init() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// read some specific system settings to store locally for faster access
|
// read specific major system settings to store locally for faster access
|
||||||
void System::reload_settings() {
|
// this also verifies all the assigned GPIOs are valid
|
||||||
|
void System::get_settings() {
|
||||||
EMSESP::webSettingsService.read([&](WebSettings & settings) {
|
EMSESP::webSettingsService.read([&](WebSettings & settings) {
|
||||||
version_ = settings.version;
|
version_ = settings.version;
|
||||||
|
|
||||||
// rx and tx pins are validated in uart_init()
|
// GPIOs
|
||||||
rx_gpio_ = settings.rx_gpio;
|
rx_gpio_ = settings.rx_gpio;
|
||||||
tx_gpio_ = settings.tx_gpio;
|
tx_gpio_ = settings.tx_gpio;
|
||||||
|
pbutton_gpio_ = settings.pbutton_gpio;
|
||||||
pbutton_gpio_ = settings.pbutton_gpio; // validated in System::button_init()
|
dallas_gpio_ = settings.dallas_gpio;
|
||||||
|
led_gpio_ = settings.led_gpio;
|
||||||
dallas_gpio_ = is_valid_gpio(settings.dallas_gpio) ? settings.dallas_gpio : 0; // we use 0 for disabled
|
|
||||||
led_gpio_ = is_valid_gpio(settings.led_gpio) ? settings.led_gpio : 0; // we use 0 for disabled
|
|
||||||
|
|
||||||
analog_enabled_ = settings.analog_enabled;
|
analog_enabled_ = settings.analog_enabled;
|
||||||
low_clock_ = settings.low_clock;
|
low_clock_ = settings.low_clock;
|
||||||
@@ -451,16 +452,10 @@ void System::reload_settings() {
|
|||||||
locale_ = settings.locale;
|
locale_ = settings.locale;
|
||||||
developer_mode_ = settings.developer_mode;
|
developer_mode_ = settings.developer_mode;
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
// check if a pin is valid ESP32 pin and not used by application settings
|
|
||||||
bool System::is_valid_gpio(uint8_t pin, bool exclude_used) {
|
|
||||||
auto valid_gpios = valid_gpio_list(exclude_used);
|
|
||||||
return std::find(valid_gpios.begin(), valid_gpios.end(), pin) != valid_gpios.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Starts up the UART Serial bridge
|
// Starts up the UART Serial bridge
|
||||||
void System::start() {
|
void System::start() {
|
||||||
#ifndef EMSESP_STANDALONE
|
#ifndef EMSESP_STANDALONE
|
||||||
// disable bluetooth module
|
// disable bluetooth module
|
||||||
// periph_module_disable(PERIPH_BT_MODULE);
|
// periph_module_disable(PERIPH_BT_MODULE);
|
||||||
@@ -499,15 +494,15 @@ void System::start() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
commands_init(); // console & api commands
|
commands_init(); // console & api commands
|
||||||
led_init(false); // init LED
|
led_init(); // init LED
|
||||||
button_init(false); // the special button
|
button_init(); // button
|
||||||
network_init(false); // network
|
network_init(); // network
|
||||||
uart_init(false); // start UART
|
uart_init(); // start UART
|
||||||
syslog_init(); // start syslog
|
syslog_init(); // start syslog
|
||||||
}
|
}
|
||||||
|
|
||||||
// button single click
|
// button single click
|
||||||
void System::button_OnClick(PButton & b) {
|
void System::button_OnClick(PButton & b) {
|
||||||
LOG_NOTICE("Button pressed - single click");
|
LOG_NOTICE("Button pressed - single click");
|
||||||
|
|
||||||
#if defined(EMSESP_TEST)
|
#if defined(EMSESP_TEST)
|
||||||
@@ -516,10 +511,10 @@ void System::button_OnClick(PButton & b) {
|
|||||||
Test::listDir(LittleFS, "/", 3);
|
Test::listDir(LittleFS, "/", 3);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// button double click
|
// button double click
|
||||||
void System::button_OnDblClick(PButton & b) {
|
void System::button_OnDblClick(PButton & b) {
|
||||||
LOG_NOTICE("Button pressed - double click - wifi reconnect to AP");
|
LOG_NOTICE("Button pressed - double click - wifi reconnect to AP");
|
||||||
// set AP mode to always so will join AP if wifi ssid fails to connect
|
// set AP mode to always so will join AP if wifi ssid fails to connect
|
||||||
EMSESP::esp32React.getAPSettingsService()->update([&](APSettings & apSettings) {
|
EMSESP::esp32React.getAPSettingsService()->update([&](APSettings & apSettings) {
|
||||||
@@ -532,34 +527,24 @@ void System::button_OnDblClick(PButton & b) {
|
|||||||
return StateUpdateResult::CHANGED;
|
return StateUpdateResult::CHANGED;
|
||||||
});
|
});
|
||||||
EMSESP::esp32React.getNetworkSettingsService()->callUpdateHandlers(); // in case we've changed ssid or password
|
EMSESP::esp32React.getNetworkSettingsService()->callUpdateHandlers(); // in case we've changed ssid or password
|
||||||
}
|
}
|
||||||
|
|
||||||
// button long press
|
// button long press
|
||||||
void System::button_OnLongPress(PButton & b) {
|
void System::button_OnLongPress(PButton & b) {
|
||||||
LOG_NOTICE("Button pressed - long press - perform factory reset");
|
LOG_NOTICE("Button pressed - long press - perform factory reset");
|
||||||
#ifndef EMSESP_STANDALONE
|
#ifndef EMSESP_STANDALONE
|
||||||
System::command_format(nullptr, 0);
|
System::command_format(nullptr, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// button indefinite press - do nothing for now
|
// button indefinite press - do nothing for now
|
||||||
void System::button_OnVLongPress(PButton & b) {
|
void System::button_OnVLongPress(PButton & b) {
|
||||||
LOG_NOTICE("Button pressed - very long press - restart from factory/boot partition");
|
LOG_NOTICE("Button pressed - very long press - restart from factory/boot partition");
|
||||||
EMSESP::system_.system_restart("boot");
|
EMSESP::system_.system_restart("boot");
|
||||||
}
|
|
||||||
|
|
||||||
// push button
|
|
||||||
void System::button_init(bool refresh) {
|
|
||||||
if (refresh) {
|
|
||||||
reload_settings();
|
|
||||||
}
|
|
||||||
|
|
||||||
// validate button gpio
|
|
||||||
if (!is_valid_gpio(pbutton_gpio_)) {
|
|
||||||
LOG_WARNING("Invalid button GPIO. Check config.");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// push button
|
||||||
|
void System::button_init() {
|
||||||
#ifndef EMSESP_STANDALONE
|
#ifndef EMSESP_STANDALONE
|
||||||
if (!myPButton_.init(pbutton_gpio_, HIGH)) {
|
if (!myPButton_.init(pbutton_gpio_, HIGH)) {
|
||||||
LOG_WARNING("Multi-functional button not detected");
|
LOG_WARNING("Multi-functional button not detected");
|
||||||
@@ -572,21 +557,16 @@ void System::button_init(bool refresh) {
|
|||||||
myPButton_.onLongPress(BUTTON_LongPressDelay, button_OnLongPress);
|
myPButton_.onLongPress(BUTTON_LongPressDelay, button_OnLongPress);
|
||||||
myPButton_.onVLongPress(BUTTON_VLongPressDelay, button_OnVLongPress);
|
myPButton_.onVLongPress(BUTTON_VLongPressDelay, button_OnVLongPress);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the LED to on or off when in normal operating mode
|
// set the LED to on or off when in normal operating mode
|
||||||
void System::led_init(bool refresh) {
|
void System::led_init() {
|
||||||
if (refresh) {
|
|
||||||
// disabled old led port before setting new one
|
// disabled old led port before setting new one
|
||||||
if (led_gpio_) {
|
|
||||||
#if ESP_ARDUINO_VERSION_MAJOR < 3
|
#if ESP_ARDUINO_VERSION_MAJOR < 3
|
||||||
led_type_ ? neopixelWrite(led_gpio_, 0, 0, 0) : digitalWrite(led_gpio_, !LED_ON);
|
led_type_ ? neopixelWrite(led_gpio_, 0, 0, 0) : digitalWrite(led_gpio_, !LED_ON);
|
||||||
#else
|
#else
|
||||||
led_type_ ? rgbLedWrite(led_gpio_, 0, 0, 0) : digitalWrite(led_gpio_, !LED_ON);
|
led_type_ ? rgbLedWrite(led_gpio_, 0, 0, 0) : digitalWrite(led_gpio_, !LED_ON);
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
reload_settings();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((led_gpio_)) { // 0 means disabled
|
if ((led_gpio_)) { // 0 means disabled
|
||||||
if (led_type_) {
|
if (led_type_) {
|
||||||
@@ -603,26 +583,19 @@ void System::led_init(bool refresh) {
|
|||||||
} else {
|
} else {
|
||||||
LOG_INFO("LED disabled");
|
LOG_INFO("LED disabled");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void System::uart_init(bool refresh) {
|
|
||||||
if (refresh) {
|
|
||||||
reload_settings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void System::uart_init() {
|
||||||
EMSuart::stop();
|
EMSuart::stop();
|
||||||
|
|
||||||
// start UART if we have valid rx and tx GPIOs
|
// start UART, GPIOs have already been checked
|
||||||
if (is_valid_gpio(rx_gpio_) && is_valid_gpio(tx_gpio_)) {
|
EMSuart::start(tx_mode_, rx_gpio_, tx_gpio_);
|
||||||
EMSuart::start(tx_mode_, rx_gpio_, tx_gpio_); // start UART
|
|
||||||
} else {
|
|
||||||
LOG_WARNING("Invalid UART Rx/Tx GPIOs. Check config.");
|
|
||||||
}
|
|
||||||
|
|
||||||
EMSESP::txservice_.start(); // reset counters and send devices request
|
EMSESP::txservice_.start(); // reset counters and send devices request
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks system health and handles LED flashing wizardry
|
// checks system health and handles LED flashing wizardry
|
||||||
void System::loop() {
|
void System::loop() {
|
||||||
// check if we're supposed to do a reset/restart
|
// check if we're supposed to do a reset/restart
|
||||||
if (systemStatus() == SYSTEM_STATUS::SYSTEM_STATUS_RESTART_REQUESTED) {
|
if (systemStatus() == SYSTEM_STATUS::SYSTEM_STATUS_RESTART_REQUESTED) {
|
||||||
system_restart();
|
system_restart();
|
||||||
@@ -640,11 +613,11 @@ void System::loop() {
|
|||||||
system_check(); // check system health
|
system_check(); // check system health
|
||||||
send_info_mqtt();
|
send_info_mqtt();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// send MQTT info topic appended with the version information as JSON, as a retained flag
|
// send MQTT info topic appended with the version information as JSON, as a retained flag
|
||||||
// this is only done once when the connection is established
|
// this is only done once when the connection is established
|
||||||
void System::send_info_mqtt() {
|
void System::send_info_mqtt() {
|
||||||
static uint8_t _connection = 0;
|
static uint8_t _connection = 0;
|
||||||
uint8_t connection = (ethernet_connected() ? 1 : 0) + ((WiFi.status() == WL_CONNECTED) ? 2 : 0) + (ntp_connected_ ? 4 : 0) + (has_ipv6_ ? 8 : 0);
|
uint8_t connection = (ethernet_connected() ? 1 : 0) + ((WiFi.status() == WL_CONNECTED) ? 2 : 0) + (ntp_connected_ ? 4 : 0) + (has_ipv6_ ? 8 : 0);
|
||||||
// check if connection status has changed
|
// check if connection status has changed
|
||||||
@@ -702,10 +675,10 @@ void System::send_info_mqtt() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
Mqtt::queue_publish_retain(F_(info), doc.as<JsonObject>()); // topic called "info" and it's Retained
|
Mqtt::queue_publish_retain(F_(info), doc.as<JsonObject>()); // topic called "info" and it's Retained
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the json for heartbeat
|
// create the json for heartbeat
|
||||||
void System::heartbeat_json(JsonObject output) {
|
void System::heartbeat_json(JsonObject output) {
|
||||||
switch (EMSESP::bus_status()) {
|
switch (EMSESP::bus_status()) {
|
||||||
case EMSESP::BUS_STATUS_OFFLINE:
|
case EMSESP::BUS_STATUS_OFFLINE:
|
||||||
output["bus_status"] = "connecting"; // EMS-ESP is booting...
|
output["bus_status"] = "connecting"; // EMS-ESP is booting...
|
||||||
@@ -759,10 +732,10 @@ void System::heartbeat_json(JsonObject output) {
|
|||||||
output["wifireconnects"] = EMSESP::esp32React.getWifiReconnects();
|
output["wifireconnects"] = EMSESP::esp32React.getWifiReconnects();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// send periodic MQTT message with system information
|
// send periodic MQTT message with system information
|
||||||
void System::send_heartbeat() {
|
void System::send_heartbeat() {
|
||||||
// don't send heartbeat if WiFi or MQTT is not connected
|
// don't send heartbeat if WiFi or MQTT is not connected
|
||||||
if (!Mqtt::connected()) {
|
if (!Mqtt::connected()) {
|
||||||
return;
|
return;
|
||||||
@@ -775,14 +748,10 @@ void System::send_heartbeat() {
|
|||||||
|
|
||||||
heartbeat_json(json);
|
heartbeat_json(json);
|
||||||
Mqtt::queue_publish(F_(heartbeat), json); // send to MQTT with retain off. This will add to MQTT queue.
|
Mqtt::queue_publish(F_(heartbeat), json); // send to MQTT with retain off. This will add to MQTT queue.
|
||||||
}
|
|
||||||
|
|
||||||
// initializes network
|
|
||||||
void System::network_init(bool refresh) {
|
|
||||||
if (refresh) {
|
|
||||||
reload_settings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initializes network
|
||||||
|
void System::network_init() {
|
||||||
last_system_check_ = 0; // force the LED to go from fast flash to pulse
|
last_system_check_ = 0; // force the LED to go from fast flash to pulse
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
@@ -821,10 +790,10 @@ void System::network_init(bool refresh) {
|
|||||||
eth_present_ = ETH.begin(type, phy_addr, mdc, mdio, power, clock_mode);
|
eth_present_ = ETH.begin(type, phy_addr, mdc, mdio, power, clock_mode);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// check health of system, done every 5 seconds
|
// check health of system, done every 5 seconds
|
||||||
void System::system_check() {
|
void System::system_check() {
|
||||||
if (!last_system_check_ || ((uint32_t)(uuid::get_uptime() - last_system_check_) >= SYSTEM_CHECK_FREQUENCY)) {
|
if (!last_system_check_ || ((uint32_t)(uuid::get_uptime() - last_system_check_) >= SYSTEM_CHECK_FREQUENCY)) {
|
||||||
last_system_check_ = uuid::get_uptime();
|
last_system_check_ = uuid::get_uptime();
|
||||||
|
|
||||||
@@ -886,11 +855,11 @@ void System::system_check() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// commands - takes static function pointers
|
// commands - takes static function pointers
|
||||||
// can be called via Console using 'call system <cmd>'
|
// can be called via Console using 'call system <cmd>'
|
||||||
void System::commands_init() {
|
void System::commands_init() {
|
||||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(read), System::command_read, FL_(read_cmd), CommandFlag::ADMIN_ONLY);
|
Command::add(EMSdevice::DeviceType::SYSTEM, F_(read), System::command_read, FL_(read_cmd), CommandFlag::ADMIN_ONLY);
|
||||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(send), System::command_send, FL_(send_cmd), CommandFlag::ADMIN_ONLY);
|
Command::add(EMSdevice::DeviceType::SYSTEM, F_(send), System::command_send, FL_(send_cmd), CommandFlag::ADMIN_ONLY);
|
||||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(fetch), System::command_fetch, FL_(fetch_cmd), CommandFlag::ADMIN_ONLY);
|
Command::add(EMSdevice::DeviceType::SYSTEM, F_(fetch), System::command_fetch, FL_(fetch_cmd), CommandFlag::ADMIN_ONLY);
|
||||||
@@ -907,13 +876,13 @@ void System::commands_init() {
|
|||||||
|
|
||||||
// MQTT subscribe "ems-esp/system/#"
|
// MQTT subscribe "ems-esp/system/#"
|
||||||
Mqtt::subscribe(EMSdevice::DeviceType::SYSTEM, "system/#", nullptr); // use empty function callback
|
Mqtt::subscribe(EMSdevice::DeviceType::SYSTEM, "system/#", nullptr); // use empty function callback
|
||||||
}
|
}
|
||||||
|
|
||||||
// uses LED to show system health
|
// uses LED to show system health
|
||||||
// 1 x flash = the EMS bus is not connected
|
// 1 x flash = the EMS bus is not connected
|
||||||
// 2 x flash = the network (wifi or ethernet) is not connected
|
// 2 x flash = the network (wifi or ethernet) is not connected
|
||||||
// 3 x flash = both EMS bus and network are failing. This is a critical error!
|
// 3 x flash = both EMS bus and network are failing. This is a critical error!
|
||||||
void System::led_monitor() {
|
void System::led_monitor() {
|
||||||
// we only need to run the LED healthcheck if there are errors
|
// we only need to run the LED healthcheck if there are errors
|
||||||
if (!healthcheck_ || !led_gpio_) {
|
if (!healthcheck_ || !led_gpio_) {
|
||||||
return; // all good
|
return; // all good
|
||||||
@@ -1013,14 +982,14 @@ void System::led_monitor() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the quality (Received Signal Strength Indicator) of the WiFi network as a %
|
// Return the quality (Received Signal Strength Indicator) of the WiFi network as a %
|
||||||
// High quality: 90% ~= -55dBm
|
// High quality: 90% ~= -55dBm
|
||||||
// Medium quality: 50% ~= -75dBm
|
// Medium quality: 50% ~= -75dBm
|
||||||
// Low quality: 30% ~= -85dBm
|
// Low quality: 30% ~= -85dBm
|
||||||
// Unusable quality: 8% ~= -96dBm
|
// Unusable quality: 8% ~= -96dBm
|
||||||
int8_t System::wifi_quality(int8_t dBm) {
|
int8_t System::wifi_quality(int8_t dBm) {
|
||||||
if (dBm <= -100) {
|
if (dBm <= -100) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1029,10 +998,10 @@ int8_t System::wifi_quality(int8_t dBm) {
|
|||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
return 2 * (dBm + 100);
|
return 2 * (dBm + 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
// print users to console
|
// print users to console
|
||||||
void System::show_users(uuid::console::Shell & shell) {
|
void System::show_users(uuid::console::Shell & shell) {
|
||||||
shell.printfln("Users:");
|
shell.printfln("Users:");
|
||||||
|
|
||||||
#ifndef EMSESP_STANDALONE
|
#ifndef EMSESP_STANDALONE
|
||||||
@@ -1044,10 +1013,10 @@ void System::show_users(uuid::console::Shell & shell) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
shell.println();
|
shell.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
// shell command 'show system'
|
// shell command 'show system'
|
||||||
void System::show_system(uuid::console::Shell & shell) {
|
void System::show_system(uuid::console::Shell & shell) {
|
||||||
refreshHeapMem(); // refresh free heap and max alloc heap
|
refreshHeapMem(); // refresh free heap and max alloc heap
|
||||||
|
|
||||||
shell.println();
|
shell.println();
|
||||||
@@ -1184,11 +1153,11 @@ void System::show_system(uuid::console::Shell & shell) {
|
|||||||
shell.println();
|
shell.println();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// see if there is a restore of an older settings file that needs to be applied
|
// see if there is a restore of an older settings file that needs to be applied
|
||||||
// note there can be only one file at a time
|
// note there can be only one file at a time
|
||||||
bool System::check_restore() {
|
bool System::check_restore() {
|
||||||
bool reboot_required = false; // true if we need to reboot
|
bool reboot_required = false; // true if we need to reboot
|
||||||
|
|
||||||
#ifndef EMSESP_STANDALONE
|
#ifndef EMSESP_STANDALONE
|
||||||
@@ -1240,12 +1209,12 @@ bool System::check_restore() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
return reboot_required;
|
return reboot_required;
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle upgrades from previous versions
|
// handle upgrades from previous versions
|
||||||
// this function will not be called on a clean install, with no settings files yet created
|
// this function will not be called on a clean install, with no settings files yet created
|
||||||
// returns true if we need a reboot
|
// returns true if we need a reboot
|
||||||
bool System::check_upgrade(bool factory_settings) {
|
bool System::check_upgrade(bool factory_settings) {
|
||||||
bool missing_version = true;
|
bool missing_version = true;
|
||||||
std::string settingsVersion;
|
std::string settingsVersion;
|
||||||
|
|
||||||
@@ -1266,7 +1235,7 @@ bool System::check_upgrade(bool factory_settings) {
|
|||||||
version::Semver200_version settings_version(settingsVersion);
|
version::Semver200_version settings_version(settingsVersion);
|
||||||
|
|
||||||
if (!missing_version) {
|
if (!missing_version) {
|
||||||
LOG_DEBUG("Checking for version upgrades (settings file has v%d.%d.%d-%s)",
|
LOG_DEBUG("Checking for version upgrades (settings file is from v%d.%d.%d-%s)",
|
||||||
settings_version.major(),
|
settings_version.major(),
|
||||||
settings_version.minor(),
|
settings_version.minor(),
|
||||||
settings_version.patch(),
|
settings_version.patch(),
|
||||||
@@ -1365,10 +1334,10 @@ bool System::check_upgrade(bool factory_settings) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert settings file into json object
|
// convert settings file into json object
|
||||||
void System::extractSettings(const char * filename, const char * section, JsonObject output) {
|
void System::extractSettings(const char * filename, const char * section, JsonObject output) {
|
||||||
#ifndef EMSESP_STANDALONE
|
#ifndef EMSESP_STANDALONE
|
||||||
File settingsFile = LittleFS.open(filename);
|
File settingsFile = LittleFS.open(filename);
|
||||||
if (settingsFile) {
|
if (settingsFile) {
|
||||||
@@ -1384,10 +1353,10 @@ void System::extractSettings(const char * filename, const char * section, JsonOb
|
|||||||
}
|
}
|
||||||
settingsFile.close();
|
settingsFile.close();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// save settings file using input from a json object
|
// save settings file using input from a json object
|
||||||
bool System::saveSettings(const char * filename, const char * section, JsonObject input) {
|
bool System::saveSettings(const char * filename, const char * section, JsonObject input) {
|
||||||
#ifndef EMSESP_STANDALONE
|
#ifndef EMSESP_STANDALONE
|
||||||
JsonObject section_json = input[section];
|
JsonObject section_json = input[section];
|
||||||
if (section_json) {
|
if (section_json) {
|
||||||
@@ -1401,10 +1370,10 @@ bool System::saveSettings(const char * filename, const char * section, JsonObjec
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return false; // not found
|
return false; // not found
|
||||||
}
|
}
|
||||||
|
|
||||||
// set a entity of services 'network', 'settings', 'mqtt', etc.
|
// set a entity of services 'network', 'settings', 'mqtt', etc.
|
||||||
bool System::command_service(const char * cmd, const char * value) {
|
bool System::command_service(const char * cmd, const char * value) {
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
bool b;
|
bool b;
|
||||||
if (Helpers::value2bool(value, b)) {
|
if (Helpers::value2bool(value, b)) {
|
||||||
@@ -1487,10 +1456,10 @@ bool System::command_service(const char * cmd, const char * value) {
|
|||||||
LOG_INFO("System command '%s' with value '%s'", cmd, value);
|
LOG_INFO("System command '%s' with value '%s'", cmd, value);
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return back a system value
|
// return back a system value
|
||||||
bool System::get_value_info(JsonObject output, const char * cmd) {
|
bool System::get_value_info(JsonObject output, const char * cmd) {
|
||||||
if (cmd == nullptr || strlen(cmd) == 0) {
|
if (cmd == nullptr || strlen(cmd) == 0) {
|
||||||
LOG_ERROR("empty system command");
|
LOG_ERROR("empty system command");
|
||||||
return false;
|
return false;
|
||||||
@@ -1562,9 +1531,9 @@ bool System::get_value_info(JsonObject output, const char * cmd) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::get_value_json(JsonObject output, const std::string & circuit, const std::string & name, JsonVariant val) {
|
void System::get_value_json(JsonObject output, const std::string & circuit, const std::string & name, JsonVariant val) {
|
||||||
output["name"] = name;
|
output["name"] = name;
|
||||||
if (circuit.length()) {
|
if (circuit.length()) {
|
||||||
output["circuit"] = circuit;
|
output["circuit"] = circuit;
|
||||||
@@ -1582,11 +1551,11 @@ void System::get_value_json(JsonObject output, const std::string & circuit, cons
|
|||||||
output["value"] = val.as<std::string>();
|
output["value"] = val.as<std::string>();
|
||||||
output["type"] = "string";
|
output["type"] = "string";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// export status information including the device information
|
// export status information including the device information
|
||||||
// http://ems-esp/api/system/info
|
// http://ems-esp/api/system/info
|
||||||
bool System::command_info(const char * value, const int8_t id, JsonObject output) {
|
bool System::command_info(const char * value, const int8_t id, JsonObject output) {
|
||||||
JsonObject node;
|
JsonObject node;
|
||||||
|
|
||||||
// System
|
// System
|
||||||
@@ -1920,30 +1889,30 @@ bool System::command_info(const char * value, const int8_t id, JsonObject output
|
|||||||
}
|
}
|
||||||
|
|
||||||
return true; // this function always returns true!
|
return true; // this function always returns true!
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(EMSESP_TEST)
|
#if defined(EMSESP_TEST)
|
||||||
// run a test, e.g. http://ems-esp/api?device=system&cmd=test&data=boiler
|
// run a test, e.g. http://ems-esp/api?device=system&cmd=test&data=boiler
|
||||||
bool System::command_test(const char * value, const int8_t id) {
|
bool System::command_test(const char * value, const int8_t id) {
|
||||||
if (value) {
|
if (value) {
|
||||||
return Test::test(value, id);
|
return Test::test(value, id);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// takes a board profile and populates a data array with GPIO configurations
|
// takes a board profile and populates a data array with GPIO configurations
|
||||||
// returns false if profile is unknown
|
// returns false if profile is unknown
|
||||||
//
|
//
|
||||||
// data = led, dallas, rx, tx, button, phy_type, eth_power, eth_phy_addr, eth_clock_mode, led_type
|
// data = led, dallas, rx, tx, button, phy_type, eth_power, eth_phy_addr, eth_clock_mode, led_type
|
||||||
//
|
//
|
||||||
// clock modes:
|
// clock modes:
|
||||||
// 0 = RMII clock input to GPIO0
|
// 0 = RMII clock input to GPIO0
|
||||||
// 1 = RMII clock output from GPIO0
|
// 1 = RMII clock output from GPIO0
|
||||||
// 2 = RMII clock output from GPIO16
|
// 2 = RMII clock output from GPIO16
|
||||||
// 3 = RMII clock output from GPIO17, for 50hz inverted clock
|
// 3 = RMII clock output from GPIO17, for 50hz inverted clock
|
||||||
bool System::load_board_profile(std::vector<int8_t> & data, const std::string & board_profile) {
|
bool System::load_board_profile(std::vector<int8_t> & data, const std::string & board_profile) {
|
||||||
if (board_profile == "S32") {
|
if (board_profile == "S32") {
|
||||||
data = {2, 18, 23, 5, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0, 0}; // BBQKees Gateway S32
|
data = {2, 18, 23, 5, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0, 0}; // BBQKees Gateway S32
|
||||||
} else if (board_profile == "E32") {
|
} else if (board_profile == "E32") {
|
||||||
@@ -1993,10 +1962,10 @@ bool System::load_board_profile(std::vector<int8_t> & data, const std::string &
|
|||||||
|
|
||||||
// LOG_DEBUG("Found data for board profile %s", board_profile.c_str());
|
// LOG_DEBUG("Found data for board profile %s", board_profile.c_str());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// format command - factory reset, removing all config files
|
// format command - factory reset, removing all config files
|
||||||
bool System::command_format(const char * value, const int8_t id) {
|
bool System::command_format(const char * value, const int8_t id) {
|
||||||
LOG_INFO("Formatting FS, removing all config files");
|
LOG_INFO("Formatting FS, removing all config files");
|
||||||
#ifndef EMSESP_STANDALONE
|
#ifndef EMSESP_STANDALONE
|
||||||
if (LittleFS.format()) {
|
if (LittleFS.format()) {
|
||||||
@@ -2009,10 +1978,10 @@ bool System::command_format(const char * value, const int8_t id) {
|
|||||||
// restart will be handled by the main loop
|
// restart will be handled by the main loop
|
||||||
EMSESP::system_.systemStatus(SYSTEM_STATUS::SYSTEM_STATUS_RESTART_REQUESTED);
|
EMSESP::system_.systemStatus(SYSTEM_STATUS::SYSTEM_STATUS_RESTART_REQUESTED);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// restart command - perform a hard reset (system reboot)
|
// restart command - perform a hard reset (system reboot)
|
||||||
bool System::command_restart(const char * value, const int8_t id) {
|
bool System::command_restart(const char * value, const int8_t id) {
|
||||||
if (id == 0) {
|
if (id == 0) {
|
||||||
// if it has an id then it's a web call and we need to queue the restart
|
// if it has an id then it's a web call and we need to queue the restart
|
||||||
// default id is -1 when calling /api/system/restart directly for example
|
// default id is -1 when calling /api/system/restart directly for example
|
||||||
@@ -2025,12 +1994,12 @@ bool System::command_restart(const char * value, const int8_t id) {
|
|||||||
// restart will be handled by the main loop
|
// restart will be handled by the main loop
|
||||||
EMSESP::system_.systemStatus(SYSTEM_STATUS::SYSTEM_STATUS_RESTART_REQUESTED);
|
EMSESP::system_.systemStatus(SYSTEM_STATUS::SYSTEM_STATUS_RESTART_REQUESTED);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wswitch"
|
#pragma GCC diagnostic ignored "-Wswitch"
|
||||||
|
|
||||||
std::string System::reset_reason(uint8_t cpu) const {
|
std::string System::reset_reason(uint8_t cpu) const {
|
||||||
#ifndef EMSESP_STANDALONE
|
#ifndef EMSESP_STANDALONE
|
||||||
switch (rtc_get_reset_reason(cpu)) {
|
switch (rtc_get_reset_reason(cpu)) {
|
||||||
case 1:
|
case 1:
|
||||||
@@ -2069,11 +2038,11 @@ std::string System::reset_reason(uint8_t cpu) const {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
// set NTP status
|
// set NTP status
|
||||||
void System::ntp_connected(bool b) {
|
void System::ntp_connected(bool b) {
|
||||||
if (b != ntp_connected_) {
|
if (b != ntp_connected_) {
|
||||||
if (b) {
|
if (b) {
|
||||||
LOG_INFO("NTP connected");
|
LOG_INFO("NTP connected");
|
||||||
@@ -2084,20 +2053,20 @@ void System::ntp_connected(bool b) {
|
|||||||
|
|
||||||
ntp_connected_ = b;
|
ntp_connected_ = b;
|
||||||
ntp_last_check_ = b ? uuid::get_uptime_sec() : 0;
|
ntp_last_check_ = b ? uuid::get_uptime_sec() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get NTP status
|
// get NTP status
|
||||||
bool System::ntp_connected() {
|
bool System::ntp_connected() {
|
||||||
// timeout 2 hours, ntp sync is normally every hour.
|
// timeout 2 hours, ntp sync is normally every hour.
|
||||||
if ((uuid::get_uptime_sec() - ntp_last_check_ > 7201) && ntp_connected_) {
|
if ((uuid::get_uptime_sec() - ntp_last_check_ > 7201) && ntp_connected_) {
|
||||||
ntp_connected(false);
|
ntp_connected(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ntp_connected_;
|
return ntp_connected_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// see if its a BBQKees Gateway by checking the nvs values
|
// see if its a BBQKees Gateway by checking the nvs values
|
||||||
String System::getBBQKeesGatewayDetails(uint8_t detail) {
|
String System::getBBQKeesGatewayDetails(uint8_t detail) {
|
||||||
#ifndef EMSESP_STANDALONE
|
#ifndef EMSESP_STANDALONE
|
||||||
/*
|
/*
|
||||||
if (!EMSESP::nvs_.isKey("mfg")) {
|
if (!EMSESP::nvs_.isKey("mfg")) {
|
||||||
@@ -2159,13 +2128,13 @@ String System::getBBQKeesGatewayDetails(uint8_t detail) {
|
|||||||
#else
|
#else
|
||||||
return "";
|
return "";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stream from an URL and send straight to OTA uploader service.
|
// Stream from an URL and send straight to OTA uploader service.
|
||||||
//
|
//
|
||||||
// This function needs to be called twice, 1st pass once with a url to persist it, 2nd pass with no arguments to start the upload
|
// This function needs to be called twice, 1st pass once with a url to persist it, 2nd pass with no arguments to start the upload
|
||||||
// This is to avoid timeouts in callback functions, like calling from a web hook.
|
// This is to avoid timeouts in callback functions, like calling from a web hook.
|
||||||
bool System::uploadFirmwareURL(const char * url) {
|
bool System::uploadFirmwareURL(const char * url) {
|
||||||
#ifndef EMSESP_STANDALONE
|
#ifndef EMSESP_STANDALONE
|
||||||
|
|
||||||
static String saved_url;
|
static String saved_url;
|
||||||
@@ -2250,11 +2219,11 @@ bool System::uploadFirmwareURL(const char * url) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true; // OK
|
return true; // OK
|
||||||
}
|
}
|
||||||
|
|
||||||
// read command, e.g. read <deviceID> <type ID> [offset] [length] from console or API
|
// read command, e.g. read <deviceID> <type ID> [offset] [length] from console or API
|
||||||
// from Console use quotes so: call system read "<deviceID> <type ID> [offset] [length]"
|
// from Console use quotes so: call system read "<deviceID> <type ID> [offset] [length]"
|
||||||
bool System::readCommand(const char * data) {
|
bool System::readCommand(const char * data) {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -2306,30 +2275,30 @@ bool System::readCommand(const char * data) {
|
|||||||
EMSESP::set_read_id(type_id);
|
EMSESP::set_read_id(type_id);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// system read command
|
// system read command
|
||||||
bool System::command_read(const char * value, const int8_t id) {
|
bool System::command_read(const char * value, const int8_t id) {
|
||||||
return readCommand(value);
|
return readCommand(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the system status code - SYSTEM_STATUS in system.h
|
// set the system status code - SYSTEM_STATUS in system.h
|
||||||
void System::systemStatus(uint8_t status_code) {
|
void System::systemStatus(uint8_t status_code) {
|
||||||
systemStatus_ = status_code;
|
systemStatus_ = status_code;
|
||||||
// LOG_DEBUG("Setting System status code %d", status_code);
|
// LOG_DEBUG("Setting System status code %d", status_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t System::systemStatus() {
|
uint8_t System::systemStatus() {
|
||||||
return systemStatus_;
|
return systemStatus_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// takes a string range like "6-11, 1, 23, 24-48" which has optional ranges and single values and converts to a vector of ints
|
// takes a string range like "6-11, 1, 23, 24-48" which has optional ranges and single values and converts to a vector of ints
|
||||||
std::vector<uint8_t> System::string_range_to_vector(const std::string & range) {
|
std::vector<uint8_t> System::string_range_to_vector(const std::string & range) {
|
||||||
std::vector<uint8_t> valid_gpios;
|
std::vector<uint8_t> gpios;
|
||||||
std::string::size_type pos = 0;
|
std::string::size_type pos = 0;
|
||||||
std::string::size_type prev = 0;
|
std::string::size_type prev = 0;
|
||||||
|
|
||||||
auto process_part = [&valid_gpios](std::string part) {
|
auto process_part = [&gpios](std::string part) {
|
||||||
// trim whitespace
|
// trim whitespace
|
||||||
part.erase(0, part.find_first_not_of(" \t"));
|
part.erase(0, part.find_first_not_of(" \t"));
|
||||||
part.erase(part.find_last_not_of(" \t") + 1);
|
part.erase(part.find_last_not_of(" \t") + 1);
|
||||||
@@ -2341,10 +2310,10 @@ std::vector<uint8_t> System::string_range_to_vector(const std::string & range) {
|
|||||||
int start = std::stoi(part.substr(0, dash_pos));
|
int start = std::stoi(part.substr(0, dash_pos));
|
||||||
int end = std::stoi(part.substr(dash_pos + 1));
|
int end = std::stoi(part.substr(dash_pos + 1));
|
||||||
for (int i = start; i <= end; i++) {
|
for (int i = start; i <= end; i++) {
|
||||||
valid_gpios.push_back(static_cast<uint8_t>(i));
|
gpios.push_back(static_cast<uint8_t>(i));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
valid_gpios.push_back(static_cast<uint8_t>(std::stoi(part)));
|
gpios.push_back(static_cast<uint8_t>(std::stoi(part)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2356,71 +2325,106 @@ std::vector<uint8_t> System::string_range_to_vector(const std::string & range) {
|
|||||||
// handle the last part
|
// handle the last part
|
||||||
process_part(range.substr(prev));
|
process_part(range.substr(prev));
|
||||||
|
|
||||||
return valid_gpios;
|
return gpios;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initialize a list of valid GPIOs based on the ESP32 board
|
||||||
|
// notes:
|
||||||
|
// - we allow 0, which is used on some board for the button
|
||||||
|
// - we also allow input only pins are accepted (34-39) on some boards
|
||||||
|
// - and allow pins 33-38 for octal SPI for 32M vchip version on some boards
|
||||||
|
void System::set_valid_system_gpios(bool exclude_used) {
|
||||||
|
valid_system_gpios_.clear(); // reset system list
|
||||||
|
used_gpios_.clear(); // reset used list
|
||||||
|
|
||||||
// return a list of valid GPIOs for the ESP32 board that can be used
|
|
||||||
// notes:
|
|
||||||
// - we allow 0, which is used on some board for the button
|
|
||||||
// - we also allow input only pins are accepted (34-39) on some boards, excluding 39
|
|
||||||
// - and allow pins 33-38 for octal SPI for 32M vchip version on some boards
|
|
||||||
std::vector<uint8_t> System::valid_gpio_list(bool exclude_used) {
|
|
||||||
// get free gpios based on board/platform type
|
// get free gpios based on board/platform type
|
||||||
#if CONFIG_IDF_TARGET_ESP32C3
|
#if CONFIG_IDF_TARGET_ESP32C3
|
||||||
// https://www.wemos.cc/en/latest/c3/c3_mini.html
|
// https://www.wemos.cc/en/latest/c3/c3_mini.html
|
||||||
std::vector<uint8_t> valid_gpios = string_range_to_vector("0-10");
|
valid_gpios_ = string_range_to_vector("0-10");
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||||
std::vector<uint8_t> valid_gpios = string_range_to_vector("0-14, 19, 20, 21, 33-38, 45, 46");
|
valid_gpios_ = string_range_to_vector("0-14, 19, 20, 21, 33-38, 45, 46");
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||||
std::vector<uint8_t> valid_gpios = string_range_to_vector("2, 4-14, 17, 18, 21, 33-38, 45, 46");
|
valid_gpios_ = string_range_to_vector("0-2, 4-14, 17, 18, 21, 33-38, 45, 46");
|
||||||
#elif CONFIG_IDF_TARGET_ESP32 || defined(EMSESP_STANDALONE)
|
#elif CONFIG_IDF_TARGET_ESP32 || defined(EMSESP_STANDALONE)
|
||||||
std::vector<uint8_t> valid_gpios = string_range_to_vector("0, 2, 4, 5, 12-15, 18, 19, 23, 25-27, 32-39");
|
valid_system_gpios_ = string_range_to_vector("0, 2, 4, 5, 12-15, 18, 19, 23, 25-27, 32-39");
|
||||||
#else
|
#else
|
||||||
std::vector<uint8_t> valid_gpios = {};
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
// if psram is enabled remove pins 16 and 17 from the list
|
|
||||||
if (ESP.getPsramSize() > 0) {
|
if (ESP.getPsramSize() > 0) {
|
||||||
valid_gpios.erase(std::remove(valid_gpios.begin(), valid_gpios.end(), 16), valid_gpios.end());
|
// if psram is enabled remove pins 16 and 17 from the list, if set
|
||||||
valid_gpios.erase(std::remove(valid_gpios.begin(), valid_gpios.end(), 17), valid_gpios.end());
|
valid_system_gpios_.erase(std::remove(valid_system_gpios_.begin(), valid_system_gpios_.end(), 16), valid_system_gpios_.end());
|
||||||
|
valid_system_gpios_.erase(std::remove(valid_system_gpios_.begin(), valid_system_gpios_.end(), 17), valid_system_gpios_.end());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// if ethernet is enabled, remove pins 21 and 22 (I2C)
|
// check if a pin is valid ESP32 pin and if not already used, add to the used gpio list
|
||||||
|
bool System::check_valid_gpio(uint8_t pin, const char * source_name) {
|
||||||
|
bool ok = false;
|
||||||
|
// check if we're allowed to use this pin
|
||||||
|
if (std::find(valid_system_gpios_.begin(), valid_system_gpios_.end(), pin) != valid_system_gpios_.end()) {
|
||||||
|
// It's OK, now check if it's already in the used list
|
||||||
|
if (std::find(used_gpios_.begin(), used_gpios_.end(), pin) != used_gpios_.end()) {
|
||||||
|
LOG_DEBUG("GPIO %d for %s is already used", pin, source_name);
|
||||||
|
ok = false; // Pin is already used, not OK
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
LOG_DEBUG("Adding GPIO %d for %s to used list", pin, source_name);
|
||||||
|
used_gpios_.push_back(pin); // add to used list
|
||||||
|
} else {
|
||||||
|
LOG_DEBUG("GPIO %d for %s is not valid", pin, source_name);
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return a list of valid and unused GPIOs still available for use
|
||||||
|
std::vector<uint8_t> System::valid_gpio_list() {
|
||||||
|
std::vector<uint8_t> gpios;
|
||||||
|
for (const auto & gpio : valid_system_gpios_) {
|
||||||
|
if (std::find(used_gpios_.begin(), used_gpios_.end(), gpio) == used_gpios_.end()) {
|
||||||
|
gpios.push_back(gpio);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return gpios;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace emsesp
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
// if ethernet is enabled, remove pins 21 and 22 (I2C) and 1 (ETH.power)
|
||||||
if ((EMSESP::system_.ethernet_connected() || EMSESP::system_.phy_type_ != PHY_type::PHY_TYPE_NONE)) {
|
if ((EMSESP::system_.ethernet_connected() || EMSESP::system_.phy_type_ != PHY_type::PHY_TYPE_NONE)) {
|
||||||
valid_gpios.erase(std::remove(valid_gpios.begin(), valid_gpios.end(), 21), valid_gpios.end());
|
gpios_to_remove.push_back(21);
|
||||||
valid_gpios.erase(std::remove(valid_gpios.begin(), valid_gpios.end(), 22), valid_gpios.end());
|
gpios_to_remove.push_back(22);
|
||||||
|
gpios_to_remove.push_back(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// filter out GPIOs already used in application settings and analog sensors, if enabled
|
// filter out GPIOs already used in application settings and analog sensors, if enabled
|
||||||
// if dallas_gpio or led_gpio is disabled (0), don't remove it from the list (as it could be gpio 0 and valid)
|
// if dallas_gpio or led_gpio is disabled (0), don't remove it from the list (as it could be gpio 0 and valid)
|
||||||
if (exclude_used) {
|
if (exclude_used) {
|
||||||
// application settings
|
// application settings
|
||||||
for (const auto & gpio : valid_gpios) {
|
gpios_to_remove.push_back(EMSESP::system_.pbutton_gpio_);
|
||||||
if (gpio == EMSESP::system_.pbutton_gpio_
|
if (EMSESP::system_.led_gpio_ != 0) {
|
||||||
|| (gpio
|
gpios_to_remove.push_back(EMSESP::system_.led_gpio_);
|
||||||
&& ((EMSESP::system_.led_gpio_ != 0 && gpio == EMSESP::system_.led_gpio_)
|
|
||||||
|| (EMSESP::system_.dallas_gpio_ != 0 && gpio == EMSESP::system_.dallas_gpio_) || gpio == EMSESP::system_.rx_gpio_
|
|
||||||
|| gpio == EMSESP::system_.tx_gpio_))) {
|
|
||||||
valid_gpios.erase(std::remove(valid_gpios.begin(), valid_gpios.end(), gpio), valid_gpios.end());
|
|
||||||
}
|
}
|
||||||
|
if (EMSESP::system_.dallas_gpio_ != 0) {
|
||||||
|
gpios_to_remove.push_back(EMSESP::system_.dallas_gpio_);
|
||||||
}
|
}
|
||||||
|
gpios_to_remove.push_back(EMSESP::system_.rx_gpio_);
|
||||||
|
gpios_to_remove.push_back(EMSESP::system_.tx_gpio_);
|
||||||
|
|
||||||
// analog sensors
|
// analog sensors
|
||||||
if (EMSESP::system_.analog_enabled_) {
|
|
||||||
for (const auto & sensor : EMSESP::analogsensor_.sensors()) {
|
for (const auto & sensor : EMSESP::analogsensor_.sensors()) {
|
||||||
if (std::find(valid_gpios.begin(), valid_gpios.end(), sensor.gpio()) != valid_gpios.end()) {
|
if (std::find(valid_system_gpios_.begin(), valid_system_gpios_.end(), sensor.gpio()) != valid_system_gpios_.end()) {
|
||||||
valid_gpios.erase(std::find(valid_gpios.begin(), valid_gpios.end(), sensor.gpio()));
|
gpios_to_remove.push_back(sensor.gpio());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort the list of valid GPIOs. This is also done in the web interface, so client side.
|
*/
|
||||||
std::sort(valid_gpios.begin(), valid_gpios.end());
|
|
||||||
|
|
||||||
return valid_gpios;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace emsesp
|
|
||||||
|
|||||||
@@ -67,7 +67,8 @@ enum SYSTEM_STATUS : uint8_t {
|
|||||||
SYSTEM_STATUS_UPLOADING = 100,
|
SYSTEM_STATUS_UPLOADING = 100,
|
||||||
SYSTEM_STATUS_ERROR_UPLOAD = 3,
|
SYSTEM_STATUS_ERROR_UPLOAD = 3,
|
||||||
SYSTEM_STATUS_PENDING_RESTART = 4,
|
SYSTEM_STATUS_PENDING_RESTART = 4,
|
||||||
SYSTEM_STATUS_RESTART_REQUESTED = 5
|
SYSTEM_STATUS_RESTART_REQUESTED = 5,
|
||||||
|
SYSTEM_STATUS_INVALID_GPIO = 6
|
||||||
};
|
};
|
||||||
|
|
||||||
enum FUSE_VALUE : uint8_t { ALL = 0, MFG = 1, MODEL = 2, BOARD = 3, REV = 4, BATCH = 5, FUSE = 6 };
|
enum FUSE_VALUE : uint8_t { ALL = 0, MFG = 1, MODEL = 2, BOARD = 3, REV = 4, BATCH = 5, FUSE = 6 };
|
||||||
@@ -103,7 +104,7 @@ class System {
|
|||||||
void system_restart(const char * partition = nullptr);
|
void system_restart(const char * partition = nullptr);
|
||||||
|
|
||||||
void show_mem(const char * note);
|
void show_mem(const char * note);
|
||||||
void reload_settings();
|
void get_settings();
|
||||||
void syslog_init();
|
void syslog_init();
|
||||||
bool check_upgrade(bool factory_settings);
|
bool check_upgrade(bool factory_settings);
|
||||||
bool check_restore();
|
bool check_restore();
|
||||||
@@ -129,11 +130,11 @@ class System {
|
|||||||
|
|
||||||
static bool uploadFirmwareURL(const char * url = nullptr);
|
static bool uploadFirmwareURL(const char * url = nullptr);
|
||||||
|
|
||||||
void led_init(bool refresh);
|
void led_init();
|
||||||
void network_init(bool refresh);
|
void network_init();
|
||||||
void button_init(bool refresh);
|
void button_init();
|
||||||
void commands_init();
|
void commands_init();
|
||||||
void uart_init(bool refresh);
|
void uart_init();
|
||||||
|
|
||||||
void systemStatus(uint8_t status_code);
|
void systemStatus(uint8_t status_code);
|
||||||
uint8_t systemStatus();
|
uint8_t systemStatus();
|
||||||
@@ -141,7 +142,8 @@ class System {
|
|||||||
static void extractSettings(const char * filename, const char * section, JsonObject output);
|
static void extractSettings(const char * filename, const char * section, JsonObject output);
|
||||||
static bool saveSettings(const char * filename, const char * section, JsonObject input);
|
static bool saveSettings(const char * filename, const char * section, JsonObject input);
|
||||||
|
|
||||||
bool is_valid_gpio(uint8_t pin, bool exclude_used = false);
|
static bool check_valid_gpio(uint8_t pin, const char * source_name);
|
||||||
|
static std::vector<uint8_t> valid_gpio_list();
|
||||||
static bool load_board_profile(std::vector<int8_t> & data, const std::string & board_profile);
|
static bool load_board_profile(std::vector<int8_t> & data, const std::string & board_profile);
|
||||||
|
|
||||||
static bool readCommand(const char * data);
|
static bool readCommand(const char * data);
|
||||||
@@ -342,7 +344,7 @@ class System {
|
|||||||
test_set_all_active_ = n;
|
test_set_all_active_ = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<uint8_t> valid_gpio_list(bool exclude_used = false);
|
static void set_valid_system_gpios(bool exclude_used = false);
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S2
|
#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S2
|
||||||
float temperature() {
|
float temperature() {
|
||||||
@@ -391,6 +393,9 @@ class System {
|
|||||||
|
|
||||||
static std::vector<uint8_t> string_range_to_vector(const std::string & range);
|
static std::vector<uint8_t> string_range_to_vector(const std::string & range);
|
||||||
|
|
||||||
|
static std::vector<uint8_t> valid_system_gpios_; // list of valid GPIOs for the ESP32 board that can be used
|
||||||
|
static std::vector<uint8_t> used_gpios_; // list of GPIOs used by the application
|
||||||
|
|
||||||
int8_t wifi_quality(int8_t dBm);
|
int8_t wifi_quality(int8_t dBm);
|
||||||
|
|
||||||
uint8_t healthcheck_ = HEALTHCHECK_NO_NETWORK | HEALTHCHECK_NO_BUS; // start with all flags set, no wifi and no ems bus connection
|
uint8_t healthcheck_ = HEALTHCHECK_NO_NETWORK | HEALTHCHECK_NO_BUS; // start with all flags set, no wifi and no ems bus connection
|
||||||
@@ -406,7 +411,6 @@ class System {
|
|||||||
bool eth_present_ = false;
|
bool eth_present_ = false;
|
||||||
|
|
||||||
// EMS-ESP settings
|
// EMS-ESP settings
|
||||||
// copies from WebSettings class in WebSettingsService.h and loaded with reload_settings()
|
|
||||||
std::string hostname_;
|
std::string hostname_;
|
||||||
String locale_;
|
String locale_;
|
||||||
bool hide_led_;
|
bool hide_led_;
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ void TemperatureSensor::reload() {
|
|||||||
// load the service settings
|
// load the service settings
|
||||||
EMSESP::system_.dallas_gpio(0); // reset in system to check valid sensor
|
EMSESP::system_.dallas_gpio(0); // reset in system to check valid sensor
|
||||||
EMSESP::webSettingsService.read([&](WebSettings const & settings) {
|
EMSESP::webSettingsService.read([&](WebSettings const & settings) {
|
||||||
dallas_gpio_ = EMSESP::system_.is_valid_gpio(settings.dallas_gpio) ? settings.dallas_gpio : 0; // we use 0 for disabled
|
dallas_gpio_ = settings.dallas_gpio;
|
||||||
parasite_ = settings.dallas_parasite;
|
parasite_ = settings.dallas_parasite;
|
||||||
});
|
});
|
||||||
EMSESP::system_.dallas_gpio(dallas_gpio_); // set to system for checks
|
EMSESP::system_.dallas_gpio(dallas_gpio_); // set to system for checks
|
||||||
|
|||||||
@@ -118,8 +118,8 @@ StateUpdateResult WebCustomization::update(JsonObject root, WebCustomization & c
|
|||||||
for (const JsonObject analogJson : analogJsons) {
|
for (const JsonObject analogJson : analogJsons) {
|
||||||
// create each of the sensor, overwriting any previous settings
|
// create each of the sensor, overwriting any previous settings
|
||||||
// if the gpio is invalid skip the sensor
|
// if the gpio is invalid skip the sensor
|
||||||
if (!EMSESP::system_.is_valid_gpio(analogJson["gpio"].as<uint8_t>(), true)) {
|
if (!EMSESP::system_.check_valid_gpio(analogJson["gpio"].as<uint8_t>(), "Analog Sensor")) {
|
||||||
EMSESP::logger().warning("Invalid GPIO %d for Sensor %s. Skipping.",
|
EMSESP::logger().warning("Analog sensor: Invalid GPIO %d for %s. Skipping.",
|
||||||
analogJson["gpio"].as<uint8_t>(),
|
analogJson["gpio"].as<uint8_t>(),
|
||||||
analogJson["name"].as<std::string>().c_str());
|
analogJson["name"].as<std::string>().c_str());
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -145,21 +145,16 @@ void WebDataService::sensor_data(AsyncWebServerRequest * request) {
|
|||||||
obj["f"] = sensor.factor();
|
obj["f"] = sensor.factor();
|
||||||
obj["t"] = sensor.type();
|
obj["t"] = sensor.type();
|
||||||
obj["s"] = sensor.is_system();
|
obj["s"] = sensor.is_system();
|
||||||
|
|
||||||
if (sensor.type() != AnalogSensor::AnalogType::NOTUSED) {
|
|
||||||
obj["v"] = Helpers::transformNumFloat(sensor.value()); // is optional and is a float
|
obj["v"] = Helpers::transformNumFloat(sensor.value()); // is optional and is a float
|
||||||
} else {
|
|
||||||
obj["v"] = 0; // must have a value for web sorting to work
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
root["analog_enabled"] = EMSESP::analog_enabled();
|
root["analog_enabled"] = EMSESP::analog_enabled();
|
||||||
root["platform"] = EMSESP_PLATFORM;
|
root["platform"] = EMSESP_PLATFORM;
|
||||||
|
|
||||||
// send back a list of valid GPIOs that can be used for analog sensors, excluding those already used
|
// send back a list of valid and unused GPIOs still available for use
|
||||||
JsonArray valid_gpio_list = root["valid_gpio_list"].to<JsonArray>();
|
JsonArray valid_gpio_list = root["valid_gpio_list"].to<JsonArray>();
|
||||||
for (const auto & gpio : EMSESP::system_.valid_gpio_list(true)) {
|
for (const auto & gpio : EMSESP::system_.valid_gpio_list()) {
|
||||||
valid_gpio_list.add(gpio);
|
valid_gpio_list.add(gpio);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -437,7 +432,7 @@ void WebDataService::dashboard_data(AsyncWebServerRequest * request) {
|
|||||||
uint8_t count = 0;
|
uint8_t count = 0;
|
||||||
for (const auto & sensor : EMSESP::analogsensor_.sensors()) {
|
for (const auto & sensor : EMSESP::analogsensor_.sensors()) {
|
||||||
// ignore system and disabled sensors
|
// ignore system and disabled sensors
|
||||||
if (sensor.is_system() || sensor.type() == AnalogSensor::AnalogType::NOTUSED) {
|
if (sensor.is_system()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
JsonObject node = nodes.add<JsonObject>();
|
JsonObject node = nodes.add<JsonObject>();
|
||||||
|
|||||||
@@ -136,9 +136,12 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) {
|
|||||||
(int8_t)(root["led_type"] | 0)}; // 0 = LED, 1 = RGB-LED
|
(int8_t)(root["led_type"] | 0)}; // 0 = LED, 1 = RGB-LED
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
// check valid pins in this board profile
|
// check valid pins for this board profile
|
||||||
if (!EMSESP::system_.is_valid_gpio(data[0]) || !EMSESP::system_.is_valid_gpio(data[1]) || !EMSESP::system_.is_valid_gpio(data[2])
|
if (!EMSESP::system_.check_valid_gpio(data[0], "LED") || !EMSESP::system_.check_valid_gpio(data[1], "Dallas")
|
||||||
|| !EMSESP::system_.is_valid_gpio(data[3]) || !EMSESP::system_.is_valid_gpio(data[4]) || !EMSESP::system_.is_valid_gpio(data[6])) {
|
|| !EMSESP::system_.check_valid_gpio(data[2], "UART Rx") || !EMSESP::system_.check_valid_gpio(data[3], "UART Tx")
|
||||||
|
|| !EMSESP::system_.check_valid_gpio(data[4], "Button") || !EMSESP::system_.check_valid_gpio(data[6], "Ethernet")) {
|
||||||
|
// set status
|
||||||
|
EMSESP::system_.systemStatus(SYSTEM_STATUS::SYSTEM_STATUS_INVALID_GPIO);
|
||||||
settings.board_profile = "default"; // reset to factory default
|
settings.board_profile = "default"; // reset to factory default
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -417,7 +420,7 @@ void WebSettingsService::onUpdate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (WebSettings::has_flags(WebSettings::ChangeFlags::UART)) {
|
if (WebSettings::has_flags(WebSettings::ChangeFlags::UART)) {
|
||||||
EMSESP::system_.uart_init(true);
|
EMSESP::system_.uart_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WebSettings::has_flags(WebSettings::ChangeFlags::SYSLOG)) {
|
if (WebSettings::has_flags(WebSettings::ChangeFlags::SYSLOG)) {
|
||||||
@@ -429,11 +432,11 @@ void WebSettingsService::onUpdate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (WebSettings::has_flags(WebSettings::ChangeFlags::BUTTON)) {
|
if (WebSettings::has_flags(WebSettings::ChangeFlags::BUTTON)) {
|
||||||
EMSESP::system_.button_init(true);
|
EMSESP::system_.button_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WebSettings::has_flags(WebSettings::ChangeFlags::LED)) {
|
if (WebSettings::has_flags(WebSettings::ChangeFlags::LED)) {
|
||||||
EMSESP::system_.led_init(true);
|
EMSESP::system_.led_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WebSettings::has_flags(WebSettings::ChangeFlags::MQTT)) {
|
if (WebSettings::has_flags(WebSettings::ChangeFlags::MQTT)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user