mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 15:59:52 +03:00
option to set how booleans are rendered - #509
This commit is contained in:
@@ -8,12 +8,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
## [2.1]
|
## [2.1]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- boiler heatingactivated, automatic select parameter telegrams for write
|
- boiler `heatingactivated`, automatic select parameter telegrams for write
|
||||||
- boiler wWType parameter, in Console and MQTT
|
- boiler `wWType` parameter, in Console and MQTT
|
||||||
- support for uploading compressed firmware binaries in web UI
|
- support for uploading compressed firmware binaries in web UI
|
||||||
- setting to manually override the MQTT retain flag
|
- setting to manually override the MQTT retain flag
|
||||||
- New API via HTTP REST API. See https://emsesp.github.io/docs/#/API
|
- New API via HTTP REST API to read and set values. See https://emsesp.github.io/docs/#/API
|
||||||
- `show commands` command
|
- `show commands` command
|
||||||
|
- exporting of system settings using the `system info` command in Web and Console. Added link into the Web's Settings page.
|
||||||
|
- setting to change how booleans are rendered in MQTT (on/off, true/false, 1/0)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- fix wwontime readback
|
- fix wwontime readback
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ import { EMSESPSettings } from './EMSESPtypes';
|
|||||||
|
|
||||||
export const EMSESP_SETTINGS_ENDPOINT = ENDPOINT_ROOT + "emsespSettings";
|
export const EMSESP_SETTINGS_ENDPOINT = ENDPOINT_ROOT + "emsespSettings";
|
||||||
|
|
||||||
|
export const WebAPISystemInfo = window.location.origin + "/api?device=system&cmd=info";
|
||||||
|
|
||||||
type EMSESPSettingsControllerProps = RestControllerProps<EMSESPSettings>;
|
type EMSESPSettingsControllerProps = RestControllerProps<EMSESPSettings>;
|
||||||
|
|
||||||
class EMSESPSettingsController extends Component<EMSESPSettingsControllerProps> {
|
class EMSESPSettingsController extends Component<EMSESPSettingsControllerProps> {
|
||||||
@@ -49,6 +51,7 @@ function EMSESPSettingsControllerForm(props: EMSESPSettingsControllerFormProps)
|
|||||||
<Box bgcolor="info.main" p={2} mt={2} mb={2}>
|
<Box bgcolor="info.main" p={2} mt={2} mb={2}>
|
||||||
<Typography variant="body1">
|
<Typography variant="body1">
|
||||||
Customize EMS-ESP by modifying the default settings here. Refer to the <Link href="https://emsesp.github.io/docs/#/Configure-firmware?id=settings" color="primary">{'Documentation'}</Link> for descriptions of each setting.
|
Customize EMS-ESP by modifying the default settings here. Refer to the <Link href="https://emsesp.github.io/docs/#/Configure-firmware?id=settings" color="primary">{'Documentation'}</Link> for descriptions of each setting.
|
||||||
|
<p>You can also <Link target="_blank" href={WebAPISystemInfo} color="primary">{'export'}</Link> all the system settings to make a backup.</p>
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
<br></br>
|
<br></br>
|
||||||
@@ -194,6 +197,17 @@ function EMSESPSettingsControllerForm(props: EMSESPSettingsControllerFormProps)
|
|||||||
}
|
}
|
||||||
label="Enable WEB API (for write commands)"
|
label="Enable WEB API (for write commands)"
|
||||||
/>
|
/>
|
||||||
|
<SelectValidator name="bool_format"
|
||||||
|
label="Boolean Format"
|
||||||
|
value={data.bool_format}
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
onChange={handleValueChange('bool_format')}
|
||||||
|
margin="normal">
|
||||||
|
<MenuItem value={1}>on/off</MenuItem>
|
||||||
|
<MenuItem value={2}>true/false</MenuItem>
|
||||||
|
<MenuItem value={3}>1/0</MenuItem>
|
||||||
|
</SelectValidator>
|
||||||
<br></br>
|
<br></br>
|
||||||
<Typography variant="h6" color="primary" >
|
<Typography variant="h6" color="primary" >
|
||||||
Syslog
|
Syslog
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ export interface EMSESPSettings {
|
|||||||
led_gpio: number;
|
led_gpio: number;
|
||||||
hide_led: boolean;
|
hide_led: boolean;
|
||||||
api_enabled: boolean;
|
api_enabled: boolean;
|
||||||
|
bool_format: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum busConnectionStatus {
|
export enum busConnectionStatus {
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ class DummySettings {
|
|||||||
uint16_t publish_time_mixing;
|
uint16_t publish_time_mixing;
|
||||||
uint16_t publish_time_other;
|
uint16_t publish_time_other;
|
||||||
uint16_t publish_time_sensor;
|
uint16_t publish_time_sensor;
|
||||||
|
uint8_t bool_format;
|
||||||
|
|
||||||
static void read(DummySettings & settings, JsonObject & root){};
|
static void read(DummySettings & settings, JsonObject & root){};
|
||||||
static void read(DummySettings & settings){};
|
static void read(DummySettings & settings){};
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ void EMSESPSettings::read(EMSESPSettings & settings, JsonObject & root) {
|
|||||||
root["led_gpio"] = settings.led_gpio;
|
root["led_gpio"] = settings.led_gpio;
|
||||||
root["hide_led"] = settings.hide_led;
|
root["hide_led"] = settings.hide_led;
|
||||||
root["api_enabled"] = settings.api_enabled;
|
root["api_enabled"] = settings.api_enabled;
|
||||||
|
root["bool_format"] = settings.bool_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
StateUpdateResult EMSESPSettings::update(JsonObject & root, EMSESPSettings & settings) {
|
StateUpdateResult EMSESPSettings::update(JsonObject & root, EMSESPSettings & settings) {
|
||||||
@@ -61,6 +62,7 @@ StateUpdateResult EMSESPSettings::update(JsonObject & root, EMSESPSettings & set
|
|||||||
settings.led_gpio = root["led_gpio"] | EMSESP_DEFAULT_LED_GPIO;
|
settings.led_gpio = root["led_gpio"] | EMSESP_DEFAULT_LED_GPIO;
|
||||||
settings.hide_led = root["hide_led"] | EMSESP_DEFAULT_HIDE_LED;
|
settings.hide_led = root["hide_led"] | EMSESP_DEFAULT_HIDE_LED;
|
||||||
settings.api_enabled = root["api_enabled"] | EMSESP_DEFAULT_API_ENABLED;
|
settings.api_enabled = root["api_enabled"] | EMSESP_DEFAULT_API_ENABLED;
|
||||||
|
settings.bool_format = root["bool_format"] | EMSESP_DEFAULT_BOOL_FORMAT;
|
||||||
|
|
||||||
return StateUpdateResult::CHANGED;
|
return StateUpdateResult::CHANGED;
|
||||||
}
|
}
|
||||||
@@ -69,11 +71,10 @@ StateUpdateResult EMSESPSettings::update(JsonObject & root, EMSESPSettings & set
|
|||||||
// either via the Web UI or via the Console
|
// either via the Web UI or via the Console
|
||||||
void EMSESPSettingsService::onUpdate() {
|
void EMSESPSettingsService::onUpdate() {
|
||||||
EMSESP::shower_.start();
|
EMSESP::shower_.start();
|
||||||
// EMSESP::system_.syslog_init(); // changing SysLog will require a restart
|
|
||||||
EMSESP::init_tx();
|
|
||||||
System::set_led();
|
|
||||||
Sensor sensor_; // Dallas sensors
|
Sensor sensor_; // Dallas sensors
|
||||||
sensor_.start();
|
sensor_.start();
|
||||||
|
|
||||||
|
System::init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EMSESPSettingsService::begin() {
|
void EMSESPSettingsService::begin() {
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
#define EMSESP_DEFAULT_HIDE_LED false
|
#define EMSESP_DEFAULT_HIDE_LED false
|
||||||
#define EMSESP_DEFAULT_DALLAS_PARASITE false
|
#define EMSESP_DEFAULT_DALLAS_PARASITE false
|
||||||
#define EMSESP_DEFAULT_API_ENABLED true
|
#define EMSESP_DEFAULT_API_ENABLED true
|
||||||
|
#define EMSESP_DEFAULT_BOOL_FORMAT 1 // on/off
|
||||||
|
|
||||||
// Default GPIO PIN definitions
|
// Default GPIO PIN definitions
|
||||||
#if defined(ESP8266)
|
#if defined(ESP8266)
|
||||||
@@ -77,6 +78,7 @@ class EMSESPSettings {
|
|||||||
uint8_t led_gpio;
|
uint8_t led_gpio;
|
||||||
bool hide_led;
|
bool hide_led;
|
||||||
bool api_enabled;
|
bool api_enabled;
|
||||||
|
uint8_t bool_format;
|
||||||
|
|
||||||
static void read(EMSESPSettings & settings, JsonObject & root);
|
static void read(EMSESPSettings & settings, JsonObject & root);
|
||||||
static StateUpdateResult update(JsonObject & root, EMSESPSettings & settings);
|
static StateUpdateResult update(JsonObject & root, EMSESPSettings & settings);
|
||||||
|
|||||||
@@ -156,6 +156,7 @@ class EMSdevice {
|
|||||||
// format:
|
// format:
|
||||||
// for ints its 0=no division, 255=handle as boolean, other divide by the value given and render with a decimal point
|
// for ints its 0=no division, 255=handle as boolean, other divide by the value given and render with a decimal point
|
||||||
// for floats its the precision in number of decimal places from 0 to 8
|
// for floats its the precision in number of decimal places from 0 to 8
|
||||||
|
// for bools its EMS_VALUE_BOOL (0xFF)
|
||||||
template <typename Value>
|
template <typename Value>
|
||||||
static void print_value(uuid::console::Shell & shell,
|
static void print_value(uuid::console::Shell & shell,
|
||||||
uint8_t padding,
|
uint8_t padding,
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
|
uint8_t Helpers::bool_format_ = 1; // on/off
|
||||||
|
|
||||||
// like itoa but for hex, and quicker
|
// like itoa but for hex, and quicker
|
||||||
char * Helpers::hextoa(char * result, const uint8_t value) {
|
char * Helpers::hextoa(char * result, const uint8_t value) {
|
||||||
char * p = result;
|
char * p = result;
|
||||||
@@ -120,17 +122,28 @@ char * Helpers::smallitoa(char * result, const uint16_t value) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// work out how to display booleans
|
||||||
|
void Helpers::render_boolean(char * result, bool value) {
|
||||||
|
if (bool_format() == 1) {
|
||||||
|
strlcpy(result, value ? "on" : "off", 5);
|
||||||
|
} else if (bool_format() == 2) {
|
||||||
|
strlcpy(result, value ? "true" : "false", 7);
|
||||||
|
} else {
|
||||||
|
strlcpy(result, value ? "1" : "0", 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// convert unsigned int (single byte) to text value and returns it
|
// convert unsigned int (single byte) to text value and returns it
|
||||||
// format: 255=boolean, 0=no formatting, otherwise divide by format
|
// format: 255(0xFF)=boolean, 0=no formatting, otherwise divide by format
|
||||||
char * Helpers::render_value(char * result, uint8_t value, uint8_t format) {
|
char * Helpers::render_value(char * result, uint8_t value, uint8_t format) {
|
||||||
// special check if its a boolean
|
// special check if its a boolean
|
||||||
if (format == EMS_VALUE_BOOL) {
|
if (format == EMS_VALUE_BOOL) {
|
||||||
if (value == EMS_VALUE_BOOL_OFF) {
|
if (value == EMS_VALUE_BOOL_OFF) {
|
||||||
strlcpy(result, "off", 5);
|
render_boolean(result, false);
|
||||||
} else if (value == EMS_VALUE_BOOL_NOTSET) {
|
} else if (value == EMS_VALUE_BOOL_NOTSET) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
} else {
|
} else {
|
||||||
strlcpy(result, "on", 5); // assume on. could have value 0x01 or 0xFF
|
render_boolean(result, true); // assume on. could have value 0x01 or 0xFF
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -169,9 +182,11 @@ char * Helpers::render_value(char * result, const float value, const uint8_t for
|
|||||||
char * ret = result;
|
char * ret = result;
|
||||||
long whole = (long)value;
|
long whole = (long)value;
|
||||||
Helpers::itoa(result, whole, 10);
|
Helpers::itoa(result, whole, 10);
|
||||||
|
|
||||||
while (*result != '\0') {
|
while (*result != '\0') {
|
||||||
result++;
|
result++;
|
||||||
}
|
}
|
||||||
|
|
||||||
*result++ = '.';
|
*result++ = '.';
|
||||||
long decimal = abs((long)((value - whole) * p[format]));
|
long decimal = abs((long)((value - whole) * p[format]));
|
||||||
itoa(result, decimal, 10);
|
itoa(result, decimal, 10);
|
||||||
@@ -329,27 +344,27 @@ bool Helpers::check_abs(const int32_t i) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// for booleans, use isBool true (EMS_VALUE_BOOL)
|
// for booleans, use isBool true (EMS_VALUE_BOOL)
|
||||||
bool Helpers::hasValue(const uint8_t &v, const uint8_t isBool) {
|
bool Helpers::hasValue(const uint8_t & v, const uint8_t isBool) {
|
||||||
if (isBool == EMS_VALUE_BOOL) {
|
if (isBool == EMS_VALUE_BOOL) {
|
||||||
return (v != EMS_VALUE_BOOL_NOTSET);
|
return (v != EMS_VALUE_BOOL_NOTSET);
|
||||||
}
|
}
|
||||||
return (v != EMS_VALUE_UINT_NOTSET);
|
return (v != EMS_VALUE_UINT_NOTSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Helpers::hasValue(const int8_t &v) {
|
bool Helpers::hasValue(const int8_t & v) {
|
||||||
return (v != EMS_VALUE_INT_NOTSET);
|
return (v != EMS_VALUE_INT_NOTSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
// for short these are typically 0x8300, 0x7D00 and sometimes 0x8000
|
// for short these are typically 0x8300, 0x7D00 and sometimes 0x8000
|
||||||
bool Helpers::hasValue(const int16_t &v) {
|
bool Helpers::hasValue(const int16_t & v) {
|
||||||
return (abs(v) < EMS_VALUE_USHORT_NOTSET);
|
return (abs(v) < EMS_VALUE_USHORT_NOTSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Helpers::hasValue(const uint16_t &v) {
|
bool Helpers::hasValue(const uint16_t & v) {
|
||||||
return (v < EMS_VALUE_USHORT_NOTSET);
|
return (v < EMS_VALUE_USHORT_NOTSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Helpers::hasValue(const uint32_t &v) {
|
bool Helpers::hasValue(const uint32_t & v) {
|
||||||
return (v != EMS_VALUE_ULONG_NOTSET);
|
return (v != EMS_VALUE_ULONG_NOTSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ class Helpers {
|
|||||||
static char * render_value(char * result, const uint32_t value, const uint8_t format);
|
static char * render_value(char * result, const uint32_t value, const uint8_t format);
|
||||||
static char * render_value(char * result, const int16_t value, const uint8_t format);
|
static char * render_value(char * result, const int16_t value, const uint8_t format);
|
||||||
|
|
||||||
|
static void render_boolean(char * result, bool value);
|
||||||
|
|
||||||
static char * smallitoa(char * result, const uint8_t value);
|
static char * smallitoa(char * result, const uint8_t value);
|
||||||
static char * smallitoa(char * result, const uint16_t value);
|
static char * smallitoa(char * result, const uint16_t value);
|
||||||
static char * itoa(char * result, int16_t value, const uint8_t base = 10);
|
static char * itoa(char * result, int16_t value, const uint8_t base = 10);
|
||||||
@@ -46,15 +48,23 @@ class Helpers {
|
|||||||
static bool check_abs(const int32_t i);
|
static bool check_abs(const int32_t i);
|
||||||
static double round2(double value);
|
static double round2(double value);
|
||||||
|
|
||||||
|
static void bool_format(uint8_t bool_format) {
|
||||||
|
bool_format_ = bool_format;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t bool_format() {
|
||||||
|
return bool_format_;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef EMSESP_STANDALONE
|
#ifdef EMSESP_STANDALONE
|
||||||
static char * ultostr(char * ptr, uint32_t value, const uint8_t base);
|
static char * ultostr(char * ptr, uint32_t value, const uint8_t base);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool hasValue(const uint8_t &v, const uint8_t isBool = 0);
|
static bool hasValue(const uint8_t & v, const uint8_t isBool = 0);
|
||||||
static bool hasValue(const int8_t &v);
|
static bool hasValue(const int8_t & v);
|
||||||
static bool hasValue(const int16_t &v);
|
static bool hasValue(const int16_t & v);
|
||||||
static bool hasValue(const uint16_t &v);
|
static bool hasValue(const uint16_t & v);
|
||||||
static bool hasValue(const uint32_t &v);
|
static bool hasValue(const uint32_t & v);
|
||||||
|
|
||||||
static std::string toLower(std::string const & s);
|
static std::string toLower(std::string const & s);
|
||||||
|
|
||||||
@@ -62,6 +72,9 @@ class Helpers {
|
|||||||
static bool value2float(const char * v, float & value);
|
static bool value2float(const char * v, float & value);
|
||||||
static bool value2bool(const char * v, bool & value);
|
static bool value2bool(const char * v, bool & value);
|
||||||
static bool value2string(const char * v, std::string & value);
|
static bool value2string(const char * v, std::string & value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static uint8_t bool_format_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
|
|||||||
@@ -152,9 +152,6 @@ void System::start() {
|
|||||||
EMSESP::esp8266React.getWiFiSettingsService()->read(
|
EMSESP::esp8266React.getWiFiSettingsService()->read(
|
||||||
[&](WiFiSettings & wifiSettings) { LOG_INFO(F("System %s booted (EMS-ESP version %s)"), wifiSettings.hostname.c_str(), EMSESP_APP_VERSION); });
|
[&](WiFiSettings & wifiSettings) { LOG_INFO(F("System %s booted (EMS-ESP version %s)"), wifiSettings.hostname.c_str(), EMSESP_APP_VERSION); });
|
||||||
|
|
||||||
syslog_init(); // init SysLog
|
|
||||||
set_led(); // init LED
|
|
||||||
|
|
||||||
// these commands respond to the topic "system" and take a payload like {cmd:"", data:"", id:""}
|
// these commands respond to the topic "system" and take a payload like {cmd:"", data:"", id:""}
|
||||||
EMSESP::emsespSettingsService.read([&](EMSESPSettings & settings) {
|
EMSESP::emsespSettingsService.read([&](EMSESPSettings & settings) {
|
||||||
Command::add(EMSdevice::DeviceType::SYSTEM, settings.ems_bus_id, F("pin"), System::command_pin);
|
Command::add(EMSdevice::DeviceType::SYSTEM, settings.ems_bus_id, F("pin"), System::command_pin);
|
||||||
@@ -162,6 +159,18 @@ void System::start() {
|
|||||||
Command::add_with_json(EMSdevice::DeviceType::SYSTEM, F("info"), System::command_info);
|
Command::add_with_json(EMSdevice::DeviceType::SYSTEM, F("info"), System::command_info);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
syslog_init(); // init SysLog
|
||||||
|
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
// init stuff. This is called when settings are changed in the web
|
||||||
|
void System::init() {
|
||||||
|
set_led(); // init LED
|
||||||
|
|
||||||
|
// set the boolean format used for rendering booleans
|
||||||
|
EMSESP::emsespSettingsService.read([&](EMSESPSettings & settings) { Helpers::bool_format(settings.bool_format); });
|
||||||
|
|
||||||
EMSESP::init_tx(); // start UART
|
EMSESP::init_tx(); // start UART
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -897,6 +906,8 @@ bool System::command_info(const char * value, const int8_t id, JsonObject & outp
|
|||||||
node["dallas_parasite"] = settings.dallas_parasite;
|
node["dallas_parasite"] = settings.dallas_parasite;
|
||||||
node["led_gpio"] = settings.led_gpio;
|
node["led_gpio"] = settings.led_gpio;
|
||||||
node["hide_led"] = settings.hide_led;
|
node["hide_led"] = settings.hide_led;
|
||||||
|
node["api_enabled"] = settings.api_enabled;
|
||||||
|
node["bool_format"] = settings.bool_format;
|
||||||
});
|
});
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ class System {
|
|||||||
static bool upload_status();
|
static bool upload_status();
|
||||||
static void show_mem(const char * note);
|
static void show_mem(const char * note);
|
||||||
static void set_led();
|
static void set_led();
|
||||||
|
static void init();
|
||||||
|
|
||||||
bool check_upgrade();
|
bool check_upgrade();
|
||||||
void syslog_init();
|
void syslog_init();
|
||||||
|
|||||||
Reference in New Issue
Block a user