mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-09 09:19:51 +03:00
added ethernet phy type as an option in settings - #210
This commit is contained in:
@@ -762,32 +762,33 @@ void Console::load_system_commands(unsigned int context) {
|
||||
EMSESP::dallassensor_.update(arguments.front().c_str(), arguments[1].c_str(), offset);
|
||||
});
|
||||
|
||||
EMSESPShell::commands
|
||||
->add_command(context,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F_(set), F_(board_profile)},
|
||||
flash_string_vector{F_(name_mandatory)},
|
||||
[](Shell & shell, const std::vector<std::string> & arguments) {
|
||||
std::vector<uint8_t> data; // led, dallas, rx, tx, button
|
||||
std::string board_profile = Helpers::toUpper(arguments.front());
|
||||
if (!EMSESP::system_.load_board_profile(data, board_profile)) {
|
||||
shell.println(F("Invalid board profile (S32, E32, MH-ET, NODEMCU, OLIMEX, TLK110, LAN8720, CUSTOM)"));
|
||||
return;
|
||||
}
|
||||
EMSESP::webSettingsService.update(
|
||||
[&](WebSettings & settings) {
|
||||
settings.board_profile = board_profile.c_str();
|
||||
settings.led_gpio = data[0];
|
||||
settings.dallas_gpio = data[1];
|
||||
settings.rx_gpio = data[2];
|
||||
settings.tx_gpio = data[3];
|
||||
settings.pbutton_gpio = data[4];
|
||||
return StateUpdateResult::CHANGED;
|
||||
},
|
||||
"local");
|
||||
shell.printfln("Loaded board profile %s (%d,%d,%d,%d,%d)", board_profile.c_str(), data[0], data[1], data[2], data[3], data[4]);
|
||||
EMSESP::system_.network_init(true);
|
||||
});
|
||||
EMSESPShell::commands->add_command(
|
||||
context,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F_(set), F_(board_profile)},
|
||||
flash_string_vector{F_(name_mandatory)},
|
||||
[](Shell & shell, const std::vector<std::string> & arguments) {
|
||||
std::vector<uint8_t> data; // led, dallas, rx, tx, button
|
||||
std::string board_profile = Helpers::toUpper(arguments.front());
|
||||
if (!EMSESP::system_.load_board_profile(data, board_profile)) {
|
||||
shell.println(F("Invalid board profile (S32, E32, MH-ET, NODEMCU, OLIMEX, CUSTOM)"));
|
||||
return;
|
||||
}
|
||||
EMSESP::webSettingsService.update(
|
||||
[&](WebSettings & settings) {
|
||||
settings.board_profile = board_profile.c_str();
|
||||
settings.led_gpio = data[0];
|
||||
settings.dallas_gpio = data[1];
|
||||
settings.rx_gpio = data[2];
|
||||
settings.tx_gpio = data[3];
|
||||
settings.pbutton_gpio = data[4];
|
||||
settings.phy_type = data[5];
|
||||
return StateUpdateResult::CHANGED;
|
||||
},
|
||||
"local");
|
||||
shell.printfln("Loaded board profile %s (%d,%d,%d,%d,%d,%d)", board_profile.c_str(), data[0], data[1], data[2], data[3], data[4], data[5]);
|
||||
EMSESP::system_.network_init(true);
|
||||
});
|
||||
EMSESPShell::commands->add_command(context,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F_(show), F_(users)},
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
#define EMSESP_DEFAULT_BOARD_PROFILE "S32" // Gateway S32
|
||||
#endif
|
||||
|
||||
// Default GPIO PIN definitions - based on Wemos/Nodemcu
|
||||
// Default GPIO PIN definitions
|
||||
|
||||
#ifndef EMSESP_DEFAULT_RX_GPIO
|
||||
#define EMSESP_DEFAULT_RX_GPIO 23 // D7
|
||||
@@ -114,6 +114,10 @@
|
||||
#define EMSESP_DEFAULT_PBUTTON_GPIO 0
|
||||
#endif
|
||||
|
||||
#ifndef EMSESP_DEFAULT_PHY_TYPE
|
||||
#define EMSESP_DEFAULT_PHY_TYPE 0 // No Ethernet, just Wifi
|
||||
#endif
|
||||
|
||||
// MQTT
|
||||
|
||||
#ifndef EMSESP_DEFAULT_BOOL_FORMAT
|
||||
|
||||
@@ -147,9 +147,9 @@ MAKE_PSTR(password_prompt, "Password: ")
|
||||
MAKE_PSTR(unset, "<unset>")
|
||||
|
||||
// command descriptions
|
||||
MAKE_PSTR(info_cmd, "list all values")
|
||||
MAKE_PSTR(commands_cmd, "list all commands")
|
||||
MAKE_PSTR(entities_cmd, "list all entities")
|
||||
MAKE_PSTR(info_cmd, "lists all values")
|
||||
MAKE_PSTR(commands_cmd, "lists all commands")
|
||||
MAKE_PSTR(entities_cmd, "lists all entities")
|
||||
|
||||
MAKE_PSTR_WORD(number)
|
||||
MAKE_PSTR_WORD(enum)
|
||||
|
||||
124
src/system.cpp
124
src/system.cpp
@@ -234,7 +234,7 @@ void System::syslog_start() {
|
||||
syslog_.hostname(hostname().c_str());
|
||||
|
||||
// register the command
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(syslog_level), System::command_syslog_level, F("change syslog level"), CommandFlag::ADMIN_ONLY);
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(syslog_level), System::command_syslog_level, F("changes syslog level"), CommandFlag::ADMIN_ONLY);
|
||||
|
||||
} else if (was_enabled) {
|
||||
// in case service is still running, this flushes the queue
|
||||
@@ -265,6 +265,9 @@ void System::get_settings() {
|
||||
|
||||
// Board profile
|
||||
board_profile_ = settings.board_profile;
|
||||
|
||||
// Ethernet PHY
|
||||
phy_type_ = settings.phy_type;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -593,9 +596,7 @@ void System::network_init(bool refresh) {
|
||||
last_system_check_ = 0; // force the LED to go from fast flash to pulse
|
||||
send_heartbeat();
|
||||
|
||||
// check board profile for those which use ethernet
|
||||
// ethernet uses lots of additional memory so we only start it when it's explicitly set in the config
|
||||
if (!board_profile_.equals("E32") && !board_profile_.equals("TLK110") && !board_profile_.equals("LAN8720") && !board_profile_.equals("OLIMEX")) {
|
||||
if (phy_type_ == PHY_type::PHY_TYPE_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -606,24 +607,14 @@ void System::network_init(bool refresh) {
|
||||
eth_phy_type_t type; // Type of the Ethernet PHY (LAN8720 or TLK110)
|
||||
eth_clock_mode_t clock_mode; // ETH_CLOCK_GPIO0_IN or ETH_CLOCK_GPIO0_OUT, ETH_CLOCK_GPIO16_OUT, ETH_CLOCK_GPIO17_OUT for 50Hz inverted clock
|
||||
|
||||
if (board_profile_.equals("E32") || board_profile_.equals("LAN8720")) {
|
||||
// BBQKees Gateway E32 (LAN8720)
|
||||
if (phy_type_ == PHY_type::PHY_TYPE_LAN8720) {
|
||||
phy_addr = 1;
|
||||
power = 16;
|
||||
mdc = 23;
|
||||
mdio = 18;
|
||||
type = ETH_PHY_LAN8720;
|
||||
clock_mode = ETH_CLOCK_GPIO0_IN;
|
||||
} else if (board_profile_.equals("OLIMEX")) {
|
||||
// Olimex ESP32-EVB (LAN8720)
|
||||
phy_addr = 0;
|
||||
power = -1;
|
||||
mdc = 23;
|
||||
mdio = 18;
|
||||
type = ETH_PHY_LAN8720;
|
||||
clock_mode = ETH_CLOCK_GPIO0_IN;
|
||||
} else if (board_profile_.equals("TLK110")) {
|
||||
// Ethernet (TLK110)
|
||||
} else if (phy_type_ == PHY_type::PHY_TYPE_TLK110) {
|
||||
phy_addr = 31;
|
||||
power = -1;
|
||||
mdc = 23;
|
||||
@@ -631,11 +622,20 @@ void System::network_init(bool refresh) {
|
||||
type = ETH_PHY_TLK110;
|
||||
clock_mode = ETH_CLOCK_GPIO0_IN;
|
||||
} else {
|
||||
return; // invalid combi
|
||||
return; // no valid profile
|
||||
}
|
||||
|
||||
// bool have_ethernet = ETH.begin(phy_addr, power, mdc, mdio, type, clock_mode);
|
||||
(void)ETH.begin(phy_addr, power, mdc, mdio, type, clock_mode);
|
||||
// special case for Olimex ESP32-EVB (LAN8720) (different power and phy_addr)
|
||||
if (board_profile_.equals("OLIMEX")) {
|
||||
phy_addr = 0;
|
||||
power = -1;
|
||||
mdc = 23;
|
||||
mdio = 18;
|
||||
type = ETH_PHY_LAN8720;
|
||||
clock_mode = ETH_CLOCK_GPIO0_IN;
|
||||
}
|
||||
|
||||
ETH.begin(phy_addr, power, mdc, mdio, type, clock_mode);
|
||||
}
|
||||
|
||||
// check health of system, done every few seconds
|
||||
@@ -672,17 +672,15 @@ void System::system_check() {
|
||||
}
|
||||
|
||||
// commands - takes static function pointers
|
||||
// these commands respond to the topic "system" and take a payload like {cmd:"", data:"", id:""}
|
||||
// no individual subscribe for pin command because id is needed
|
||||
void System::commands_init() {
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM,
|
||||
F_(pin),
|
||||
System::command_pin,
|
||||
F("set GPIO"),
|
||||
F("sets a GPIO on/off"),
|
||||
CommandFlag::MQTT_SUB_FLAG_NOSUB | CommandFlag::ADMIN_ONLY); // dont create a MQTT topic for this
|
||||
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(send), System::command_send, F("send a telegram"), CommandFlag::ADMIN_ONLY);
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(fetch), System::command_fetch, F("refresh all EMS values"), CommandFlag::ADMIN_ONLY);
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(send), System::command_send, F("sends a telegram"), CommandFlag::ADMIN_ONLY);
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(fetch), System::command_fetch, F("refreshes all EMS values"), CommandFlag::ADMIN_ONLY);
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(restart), System::command_restart, F("restarts EMS-ESP"), CommandFlag::ADMIN_ONLY);
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(watch), System::command_watch, F("watch incoming telegrams"));
|
||||
|
||||
@@ -691,12 +689,12 @@ void System::commands_init() {
|
||||
}
|
||||
|
||||
// these commands will return data in JSON format
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(info), System::command_info, F("system status"));
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(settings), System::command_settings, F("list system settings"));
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(commands), System::command_commands, F("list system commands"));
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(info), System::command_info, F("show system status"));
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(settings), System::command_settings, F("shows system settings"));
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(commands), System::command_commands, F("shows system commands"));
|
||||
|
||||
#if defined(EMSESP_DEBUG)
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F("test"), System::command_test, F("run tests"));
|
||||
Command::add(EMSdevice::DeviceType::SYSTEM, F("test"), System::command_test, F("runs a specific test"));
|
||||
#endif
|
||||
|
||||
// MQTT subscribe "ems-esp/system/#"
|
||||
@@ -929,30 +927,37 @@ bool System::command_settings(const char * value, const int8_t id, JsonObject &
|
||||
#endif
|
||||
|
||||
EMSESP::webSettingsService.read([&](WebSettings & settings) {
|
||||
node = output.createNestedObject("Settings");
|
||||
node["tx_mode"] = settings.tx_mode;
|
||||
node["ems_bus_id"] = settings.ems_bus_id;
|
||||
node = output.createNestedObject("Settings");
|
||||
|
||||
node["board_profile"] = settings.board_profile;
|
||||
node["tx_mode"] = settings.tx_mode;
|
||||
node["ems_bus_id"] = settings.ems_bus_id;
|
||||
|
||||
node["syslog_enabled"] = settings.syslog_enabled;
|
||||
node["syslog_level"] = settings.syslog_level;
|
||||
node["syslog_mark_interval"] = settings.syslog_mark_interval;
|
||||
node["syslog_host"] = settings.syslog_host;
|
||||
node["syslog_port"] = settings.syslog_port;
|
||||
node["master_thermostat"] = settings.master_thermostat;
|
||||
node["shower_timer"] = settings.shower_timer;
|
||||
node["shower_alert"] = settings.shower_alert;
|
||||
node["rx_gpio"] = settings.rx_gpio;
|
||||
node["tx_gpio"] = settings.tx_gpio;
|
||||
node["dallas_gpio"] = settings.dallas_gpio;
|
||||
node["dallas_parasite"] = settings.dallas_parasite;
|
||||
node["led_gpio"] = settings.led_gpio;
|
||||
node["hide_led"] = settings.hide_led;
|
||||
node["notoken_api"] = settings.notoken_api;
|
||||
node["dallas_format"] = settings.dallas_format;
|
||||
node["bool_format"] = settings.bool_format;
|
||||
node["enum_format"] = settings.enum_format;
|
||||
node["analog_enabled"] = settings.analog_enabled;
|
||||
node["pbutton_gpio"] = settings.pbutton_gpio;
|
||||
node["board_profile"] = settings.board_profile;
|
||||
|
||||
node["master_thermostat"] = settings.master_thermostat;
|
||||
|
||||
node["shower_timer"] = settings.shower_timer;
|
||||
node["shower_alert"] = settings.shower_alert;
|
||||
|
||||
node["rx_gpio"] = settings.rx_gpio;
|
||||
node["tx_gpio"] = settings.tx_gpio;
|
||||
node["dallas_gpio"] = settings.dallas_gpio;
|
||||
node["pbutton_gpio"] = settings.pbutton_gpio;
|
||||
node["led_gpio"] = settings.led_gpio;
|
||||
node["phy_type"] = settings.phy_type;
|
||||
|
||||
node["hide_led"] = settings.hide_led;
|
||||
node["notoken_api"] = settings.notoken_api;
|
||||
node["dallas_parasite"] = settings.dallas_parasite;
|
||||
node["dallas_format"] = settings.dallas_format;
|
||||
node["bool_format"] = settings.bool_format;
|
||||
node["enum_format"] = settings.enum_format;
|
||||
node["analog_enabled"] = settings.analog_enabled;
|
||||
});
|
||||
|
||||
return true;
|
||||
@@ -1079,27 +1084,28 @@ bool System::command_test(const char * value, const int8_t id) {
|
||||
#endif
|
||||
|
||||
// takes a board profile and populates a data array with GPIO configurations
|
||||
// data = led, dallas, rx, tx, button
|
||||
// data = led, dallas, rx, tx, button, phy_type
|
||||
// returns false if profile is not found
|
||||
bool System::load_board_profile(std::vector<uint8_t> & data, const std::string & board_profile) {
|
||||
if (board_profile == "S32") {
|
||||
data = {2, 18, 23, 5, 0}; // BBQKees Gateway S32
|
||||
data = {2, 18, 23, 5, 0, PHY_type::PHY_TYPE_NONE}; // BBQKees Gateway S32
|
||||
} else if (board_profile == "E32") {
|
||||
data = {2, 4, 5, 17, 33}; // BBQKees Gateway E32
|
||||
data = {2, 4, 5, 17, 33, PHY_type::PHY_TYPE_LAN8720}; // BBQKees Gateway E32
|
||||
} else if (board_profile == "MH-ET") {
|
||||
data = {2, 18, 23, 5, 0}; // MH-ET Live D1 Mini
|
||||
data = {2, 18, 23, 5, 0, PHY_type::PHY_TYPE_NONE}; // MH-ET Live D1 Mini
|
||||
} else if (board_profile == "NODEMCU") {
|
||||
data = {2, 18, 23, 5, 0}; // NodeMCU 32S
|
||||
data = {2, 18, 23, 5, 0, PHY_type::PHY_TYPE_NONE}; // NodeMCU 32S
|
||||
} else if (board_profile == "LOLIN") {
|
||||
data = {2, 18, 17, 16, 0}; // Lolin D32
|
||||
data = {2, 18, 17, 16, 0, PHY_type::PHY_TYPE_NONE}; // Lolin D32
|
||||
} else if (board_profile == "OLIMEX") {
|
||||
data = {0, 0, 36, 4, 34}; // Olimex ESP32-EVB (uses U1TXD/U1RXD/BUTTON, no LED or Dallas)
|
||||
} else if (board_profile == "TLK110") {
|
||||
data = {2, 4, 5, 17, 33}; // Generic Ethernet (TLK110)
|
||||
} else if (board_profile == "LAN8720") {
|
||||
data = {2, 4, 5, 17, 33}; // Generic Ethernet (LAN8720)
|
||||
data = {0, 0, 36, 4, 34, PHY_type::PHY_TYPE_LAN8720}; // Olimex ESP32-EVB (uses U1TXD/U1RXD/BUTTON, no LED or Dallas)
|
||||
} else {
|
||||
data = {EMSESP_DEFAULT_LED_GPIO, EMSESP_DEFAULT_DALLAS_GPIO, EMSESP_DEFAULT_RX_GPIO, EMSESP_DEFAULT_TX_GPIO, EMSESP_DEFAULT_PBUTTON_GPIO};
|
||||
data = {EMSESP_DEFAULT_LED_GPIO,
|
||||
EMSESP_DEFAULT_DALLAS_GPIO,
|
||||
EMSESP_DEFAULT_RX_GPIO,
|
||||
EMSESP_DEFAULT_TX_GPIO,
|
||||
EMSESP_DEFAULT_PBUTTON_GPIO,
|
||||
EMSESP_DEFAULT_PHY_TYPE};
|
||||
return (board_profile == "CUSTOM");
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,8 @@ using uuid::console::Shell;
|
||||
|
||||
namespace emsesp {
|
||||
|
||||
enum PHY_type : uint8_t { PHY_TYPE_NONE = 0, PHY_TYPE_LAN8720, PHY_TYPE_TLK110 };
|
||||
|
||||
class System {
|
||||
public:
|
||||
void start(uint32_t heap_start);
|
||||
@@ -181,6 +183,7 @@ class System {
|
||||
bool low_clock_;
|
||||
String board_profile_;
|
||||
uint8_t pbutton_gpio_;
|
||||
uint8_t phy_type_;
|
||||
int8_t syslog_level_;
|
||||
uint32_t syslog_mark_interval_;
|
||||
String syslog_host_;
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define EMSESP_APP_VERSION "3.3.0b9"
|
||||
#define EMSESP_APP_VERSION "3.3.0b10"
|
||||
|
||||
@@ -50,6 +50,7 @@ void WebSettings::read(WebSettings & settings, JsonObject & root) {
|
||||
root["shower_alert"] = settings.shower_alert;
|
||||
root["rx_gpio"] = settings.rx_gpio;
|
||||
root["tx_gpio"] = settings.tx_gpio;
|
||||
root["phy_type"] = settings.phy_type;
|
||||
root["dallas_gpio"] = settings.dallas_gpio;
|
||||
root["dallas_parasite"] = settings.dallas_parasite;
|
||||
root["led_gpio"] = settings.led_gpio;
|
||||
@@ -81,7 +82,7 @@ void WebSettings::read(WebSettings & settings, JsonObject & root) {
|
||||
// call on initialization and also when settings are updated via web or console
|
||||
StateUpdateResult WebSettings::update(JsonObject & root, WebSettings & settings) {
|
||||
// load default GPIO configuration based on board profile
|
||||
std::vector<uint8_t> data; // led, dallas, rx, tx, button
|
||||
std::vector<uint8_t> data; // led, dallas, rx, tx, button, phy_type
|
||||
|
||||
String old_board_profile = settings.board_profile;
|
||||
settings.board_profile = root["board_profile"] | EMSESP_DEFAULT_BOARD_PROFILE;
|
||||
@@ -94,6 +95,7 @@ StateUpdateResult WebSettings::update(JsonObject & root, WebSettings & settings)
|
||||
uint8_t default_rx_gpio = data[2];
|
||||
uint8_t default_tx_gpio = data[3];
|
||||
uint8_t default_pbutton_gpio = data[4];
|
||||
uint8_t default_phy_type = data[5];
|
||||
|
||||
if (old_board_profile != settings.board_profile) {
|
||||
EMSESP::logger().info(F("EMS-ESP version %s"), EMSESP_APP_VERSION);
|
||||
@@ -145,9 +147,6 @@ StateUpdateResult WebSettings::update(JsonObject & root, WebSettings & settings)
|
||||
settings.syslog_port = root["syslog_port"] | EMSESP_DEFAULT_SYSLOG_PORT;
|
||||
check_flag(prev, settings.syslog_port, ChangeFlags::SYSLOG);
|
||||
|
||||
settings.trace_raw = root["trace_raw"] | EMSESP_DEFAULT_TRACELOG_RAW;
|
||||
EMSESP::trace_raw(settings.trace_raw);
|
||||
|
||||
// adc
|
||||
prev = settings.analog_enabled;
|
||||
settings.analog_enabled = root["analog_enabled"] | EMSESP_DEFAULT_ANALOG_ENABLED;
|
||||
@@ -182,13 +181,19 @@ StateUpdateResult WebSettings::update(JsonObject & root, WebSettings & settings)
|
||||
settings.hide_led = root["hide_led"] | EMSESP_DEFAULT_HIDE_LED;
|
||||
check_flag(prev, settings.hide_led, ChangeFlags::LED);
|
||||
|
||||
//
|
||||
// next ones are settings that don't need any follow-up actions
|
||||
//
|
||||
|
||||
// these need reboots to be applied
|
||||
settings.ems_bus_id = root["ems_bus_id"] | EMSESP_DEFAULT_EMS_BUS_ID;
|
||||
settings.master_thermostat = root["master_thermostat"] | EMSESP_DEFAULT_MASTER_THERMOSTAT;
|
||||
settings.low_clock = root["low_clock"] | false;
|
||||
;
|
||||
settings.phy_type = root["phy_type"] | default_phy_type; // use whatever came from the board profile
|
||||
|
||||
settings.trace_raw = root["trace_raw"] | EMSESP_DEFAULT_TRACELOG_RAW;
|
||||
EMSESP::trace_raw(settings.trace_raw);
|
||||
|
||||
// doesn't need any follow-up actions
|
||||
settings.notoken_api = root["notoken_api"] | EMSESP_DEFAULT_NOTOKEN_API;
|
||||
settings.solar_maxflow = root["solar_maxflow"] | EMSESP_DEFAULT_SOLAR_MAXFLOW;
|
||||
|
||||
@@ -275,6 +280,7 @@ void WebSettingsService::board_profile(AsyncWebServerRequest * request, JsonVari
|
||||
root["rx_gpio"] = data[2];
|
||||
root["tx_gpio"] = data[3];
|
||||
root["pbutton_gpio"] = data[4];
|
||||
root["phy_type"] = data[5];
|
||||
} else {
|
||||
AsyncWebServerResponse * response = request->beginResponse(200);
|
||||
request->send(response);
|
||||
|
||||
@@ -60,6 +60,7 @@ class WebSettings {
|
||||
uint8_t pbutton_gpio;
|
||||
uint8_t solar_maxflow;
|
||||
String board_profile;
|
||||
uint8_t phy_type;
|
||||
uint8_t dallas_format;
|
||||
uint8_t bool_format;
|
||||
uint8_t enum_format;
|
||||
|
||||
Reference in New Issue
Block a user